/* ============================================================
   ESTILOS DE LAS APPS
   ------------------------------------------------------------
   1. Hilo de conversación (compartido por Kord, Wisp y Habitat)
   2. Kord      — el Discord falso
   3. Wisp      — la mensajería
   4. HABITAT   — el mundo virtual
   5. VAPOR     — la plataforma de juegos
   6. Reproductor
   7. Pantalla de final
   ============================================================ */

/* =========================================================
   1. HILO DE CONVERSACIÓN (compartido)
   Cada app le da su color con .estilo-*
   ========================================================= */
.hilo {
  flex: 1;
  overflow-y: auto;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-height: 0;
}

.burbuja {
  position: relative;
  max-width: 78%;
  padding: 9px 14px;
  border-radius: 16px;
  font-family: var(--fuente-texto);
  font-size: 13px;
  line-height: 1.55;
  user-select: text;
  /* Contraste de iluminación: un filo de luz arriba y sombra
     abajo. Da volumen a la burbuja sin ensuciarla con bordes. */
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.055),
    0 2px 10px rgba(0,0,0,.28);
  animation: aparecer .25s cubic-bezier(.2,.8,.2,1);
}
@keyframes aparecer {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

.burbuja.suya {
  background: var(--panel-alto);
  align-self: flex-start;
  border-bottom-left-radius: 5px;
}
.burbuja.mia {
  background: linear-gradient(150deg, var(--acento-carmesi), #c31f45);
  color: #fff;
  align-self: flex-end;
  border-bottom-right-radius: 5px;
}

.burbuja-autor {
  font-family: var(--fuente-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .2px;
  margin-bottom: 3px;
  opacity: .95;
}

.linea-sistema {
  align-self: center;
  font-size: 11px;
  color: var(--texto-tenue);
  font-style: italic;
  padding: 3px 10px;
  text-align: center;
  max-width: 90%;
  animation: aparecer .25s ease-out;
}

/* --- Nota de voz --- */
.burbuja-audio { min-width: 230px; }

.audio-linea {
  display: flex;
  align-items: center;
  gap: 10px;
}
/* Botón de play circular: disco de luz esmeralda. Es el gesto
   que más se repite en el juego, así que tiene que apetecer. */
.audio-btn {
  width: 32px; height: 32px;
  flex: 0 0 auto;
  border-radius: 50%;
  border: 1px solid rgb(var(--rgb-esmeralda) / .45);
  background: radial-gradient(circle at 35% 30%, #34d399, var(--acento-esmeralda) 70%);
  color: #04231a;
  font-size: 10px;
  font-weight: 700;
  display: grid;
  place-items: center;
  box-shadow:
    0 0 14px rgb(var(--rgb-esmeralda) / .42),
    inset 0 1px 0 rgba(255,255,255,.35);
  transition: transform .16s cubic-bezier(.2,.8,.2,1), box-shadow .22s ease, filter .16s ease;
}
.burbuja.mia .audio-btn {
  background: rgba(0,0,0,.32);
  border-color: rgba(255,255,255,.28);
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.18);
}
.audio-btn:hover {
  transform: scale(1.09);
  filter: brightness(1.06);
  box-shadow: 0 0 22px rgb(var(--rgb-esmeralda) / .72), inset 0 1px 0 rgba(255,255,255,.4);
}
.audio-btn:active { transform: scale(.96); }

.audio-info { font-size: 12px; flex: 1; }
/* Subtítulo de la nota de voz: la frase que se está oyendo. */
.audio-subs {
  margin-top: 8px;
  padding: 6px 10px;
  border-radius: 8px;
  background: rgba(0,0,0,.28);
  font-size: 12.5px;
  line-height: 1.4;
  font-style: italic;
  text-align: center;
  max-width: 280px;
}
.audio-dur  {
  font-family: var(--fuente-mono);
  font-size: 10.5px; opacity: .65;
  font-variant-numeric: tabular-nums;
}
.audio-nuevo {
  font-family: var(--fuente-mono);
  font-size: 9.5px;
  letter-spacing: .8px;
  text-transform: uppercase;
  color: var(--acento-esmeralda);
  text-shadow: 0 0 10px rgb(var(--rgb-esmeralda) / .55);
  margin-top: 5px;
}

/* --- Burbuja de foto --- */
.burbuja-foto { padding: 5px; max-width: 62%; }

.foto-mini {
  display: block;
  width: 100%;
  /* Tope de altura: con material real (fotos verticales de varios
     miles de píxeles) una sola imagen llenaba la ventana entera y
     tapaba el hilo, así que no se leía ni el mensaje que la
     acompaña. Se muestra recortada como miniatura y se abre
     completa en el lightbox al hacer clic. */
  max-height: 340px;
  object-fit: cover;
  object-position: top center;
  border-radius: 10px;
  cursor: zoom-in;
  transition: filter .2s;
}
.foto-mini:hover { filter: brightness(1.1); }

/* Vídeo dentro de la burbuja: mismo problema, mismo tope */
.video-mini {
  display: block;
  width: 100%;
  max-height: 340px;
  border-radius: 10px;
  background: #000;
}

/* Marcador cuando el archivo aún no existe: así se puede jugar
   el guion completo antes de tener las imágenes */
.foto-falta {
  padding: 26px 14px;
  border: 1px dashed var(--borde);
  border-radius: 10px;
  font-size: 11px;
  color: var(--texto-tenue);
  text-align: center;
  font-family: ui-monospace, Consolas, monospace;
  background: rgba(0,0,0,.25);
}

.foto-pie { font-size: 12px; padding: 6px 8px 2px; line-height: 1.45; }

/* =========================================================
   SLOTS DE MEDIA  (fotos/audios/vídeos que rellenas tú)
   El guion apunta a un ID de content/medios.js. Mientras no
   pongas el archivo, se ve este recuadro con el ID exacto.
   ========================================================= */
.burbuja-media { padding: 5px; max-width: 62%; }

.media-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 20px 16px;
  border: 1px dashed var(--borde);
  border-radius: 10px;
  background: rgba(0,0,0,.28);
  text-align: center;
  min-width: 200px;
}
.media-slot-ico  { font-size: 26px; opacity: .8; line-height: 1; }
.media-slot-id {
  font-family: ui-monospace, Consolas, monospace;
  font-size: 12px;
  font-weight: 700;
  color: var(--texto);
  word-break: break-all;
}
.media-slot-nota {
  font-size: 11px;
  color: var(--texto-tenue);
  line-height: 1.4;
  max-width: 260px;
}
.media-slot-video, .media-slot-webcam { border-color: #b5544f; }

/* --- Vídeo en línea dentro de la burbuja --- */
.video-cont { max-width: 100%; }
.video-mini {
  display: block;
  width: 100%;
  border-radius: 10px;
  background: #000;
}

/* =========================================================
   VENTANA DE CÁMARA FLOTANTE  (webcam pregrabada de Lexi)
   Flota en la esquina de la app, encima de la conversación.
   ========================================================= */
/* Marco reactivo a la voz: el borde respira en carmesí mientras
   transmite, como el anillo de un canal de voz activo. */
.webcam-flotante {
  /* Vive en el ESCRITORIO, no dentro de la app: se puede arrastrar a
     cualquier sitio. `left/top` los pone el JS al abrirla; `right`
     ya no vale porque en cuanto la mueves manda la izquierda.
     z-index por encima de las ventanas (que van de 10 en adelante) y
     por debajo de los avisos (7000). */
  position: absolute;
  left: 0;
  top: 46px;
  width: 300px;
  z-index: 5000;
  background: #0b0d12;
  border: 1px solid rgb(var(--rgb-carmesi) / .45);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 14px 40px rgba(0,0,0,.6), 0 0 22px rgb(var(--rgb-carmesi) / .20);
  animation: aparecer .25s ease-out, webcam-voz 2.6s ease-in-out infinite;
}
@keyframes webcam-voz {
  0%, 100% { box-shadow: 0 14px 40px rgba(0,0,0,.6), 0 0 16px rgb(var(--rgb-carmesi) / .18); }
  50%      { box-shadow: 0 14px 40px rgba(0,0,0,.6), 0 0 30px rgb(var(--rgb-carmesi) / .48); }
}
.webcam-barra {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 9px;
  cursor: grab;
  user-select: none;
  background: linear-gradient(180deg, rgba(255,255,255,.05), rgba(0,0,0,0)), #14171f;
  font-family: var(--fuente-ui);
  font-size: 11px;
}
/* Badge LIVE de neón */
.webcam-rec {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--fuente-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 1.2px;
  color: #fff;
  background: linear-gradient(135deg, var(--acento-carmesi), #ff4d6d);
  padding: 3px 8px;
  border-radius: var(--radio-capsula);
  box-shadow: 0 0 14px rgb(var(--rgb-carmesi) / .65);
  animation: webcam-parpadeo 1.4s steps(1) infinite;
}
@keyframes webcam-parpadeo { 50% { opacity: .35; } }

/* EN ESPERA: hay opciones en el chat y el vídeo está parado hasta
   que el jugador conteste (ver webcamEspera en _chat-ui.js). El REC
   se apaga y deja de parpadear, y sobre la imagen se dice por qué
   está quieta: si no, parece que se ha colgado. */
.webcam-flotante.en-espera .webcam-rec {
  animation: none;
  background: rgba(255,255,255,.14);
  box-shadow: none;
  color: var(--texto-tenue);
}
.webcam-flotante.en-espera .webcam-cuerpo::after {
  content: attr(data-espera);   /* traducido en _chat-ui.js */
  position: absolute;
  left: 50%;
  top: 10px;              /* abajo va el «✓ Guardado en tu galería» */
  transform: translateX(-50%);
  white-space: nowrap;
  padding: 5px 11px;
  border-radius: var(--radio-capsula);
  background: rgba(10,12,18,.78);
  border: 1px solid rgb(var(--rgb-violeta) / .5);
  color: #fff;
  font-family: var(--fuente-ui);
  font-size: 11px;
  letter-spacing: .2px;
  pointer-events: none;
  animation: webcamEspera .3s ease both;
}
@keyframes webcamEspera {
  from { opacity: 0; transform: translate(-50%, 4px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .webcam-flotante.en-espera .webcam-cuerpo::after { animation: none; }
}
.webcam-tit   { flex: 1; color: var(--texto); opacity: .9; }
.webcam-cerrar {
  border: none;
  background: transparent;
  color: var(--texto-tenue);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}
.webcam-cerrar:hover { color: var(--texto); }

/* =========================================================
   CONFIRMAR UNA OPCION QUE CIERRA UNA PUERTA
   Ocupa el sitio de la lista de opciones, no flota encima: el
   jugador no sale de la conversacion para decidir, solo cambia
   lo que tiene delante.
   ========================================================= */
.opcion-confirm {
  border: 1px solid rgb(var(--rgb-carmesi) / .35);
  background: rgb(var(--rgb-carmesi) / .06);
  border-radius: var(--radio);
  padding: 12px 14px;
  animation: aparecer .18s ease-out;
}
.opcion-confirm-txt {
  margin: 0 0 11px;
  font-family: var(--fuente-texto);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--texto);
}
.opcion-confirm-acc { display: flex; gap: 8px; flex-wrap: wrap; }
.opcion-confirm-btn {
  padding: 8px 14px;
  border-radius: var(--radio);
  font-family: var(--fuente-ui);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
/* Quedarse es lo que el jugador querra casi siempre: va destacado */
.opcion-confirm-btn.no {
  border: 1px solid rgb(var(--rgb-carmesi) / .5);
  background: linear-gradient(135deg, var(--acento-carmesi), #ff4d6d);
  color: #fff;
}
.opcion-confirm-btn.no:hover { box-shadow: 0 0 18px rgb(var(--rgb-carmesi) / .45); }
/* Cortar existe y se entiende, pero no se vende */
.opcion-confirm-btn.si {
  border: 1px solid var(--borde);
  background: transparent;
  color: var(--texto-tenue);
}
.opcion-confirm-btn.si:hover { border-color: var(--borde-fuerte); color: var(--texto); }

/* Minimizar. Mismo tamaño que la [X] para que el par se lea como un
   grupo de controles de ventana y no como dos cosas distintas. */
.webcam-min {
  border: none;
  background: transparent;
  color: var(--texto-tenue);
  font-size: 15px;
  line-height: 1;
  padding: 0 2px;
  cursor: pointer;
}
.webcam-min:hover { color: var(--texto); }

/* Agrandar: mismo par de controles que minimizar y cerrar */
.webcam-zoom {
  border: none;
  background: transparent;
  color: var(--texto-tenue);
  font-size: 13px;
  line-height: 1;
  padding: 0 2px;
  cursor: pointer;
}
.webcam-zoom:hover { color: var(--texto); }

/* ARRASTRANDO — el cursor dice que la tienes cogida, y se le quita
   el latido del borde para que no distraiga mientras la colocas. */
.webcam-flotante.arrastrando { animation: none; box-shadow: 0 18px 50px rgba(0,0,0,.7); }
.webcam-flotante.arrastrando .webcam-barra { cursor: grabbing; }

/* AGRANDADA = PÁGINA DE STREAM
   No es pantalla completa: es el vídeo al doble CON la conversación
   al lado. Agrandar sin más tapaba justo las opciones de Kord, y
   apartarla no arregla nada porque entonces miras a un sitio o al
   otro; esta escena son las dos cosas a la vez. */
/* TAMAÑO: el del juego, no el del navegador.
   El intento anterior quitaba la proporción del vídeo y lo metía con
   `contain` para que cupiera siempre. Cabía, sí, pero quedaba feo:
   una columna altísima con dos bandas negras enormes arriba y abajo,
   más alta que la propia ventana de Kord.

   Ahora las medidas salen del juego —una ventana suya ronda los
   860×620— y el vídeo MANDA sobre su mitad con su proporción de
   siempre. 540 de vídeo + 300 de chat = 840 de ancho y unos 440 de
   alto: del tamaño de una ventana del escritorio, que es justo lo
   que tiene que parecer. */
.webcam-flotante.grande {
  width: 840px;
  display: grid;
  grid-template-columns: 540px minmax(0, 1fr);
  /* La fila la fija el VÍDEO (540 de ancho a 4:3 son 405 de alto), no
     el contenido del chat. Con `1fr` la estiraba el que fuera más
     alto —el chat, con sus mensajes y sus botones— y al vídeo le
     quedaba una banda negra debajo. Ahora el chat se desplaza dentro
     de esos 405 y el panel tiene siempre la misma silueta. */
  grid-template-rows: auto 405px;

  /* Tope de seguridad. Se descuenta la barra de tareas (58px) para
     no taparla nunca. */
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 78px);

  border-radius: var(--radio-ventana);
  box-shadow: var(--sombra-ventana), 0 0 26px rgb(var(--rgb-carmesi) / .16);
}
.webcam-flotante.grande .webcam-barra { grid-column: 1 / -1; padding: 9px 13px; font-size: 12px; }
.webcam-flotante.grande .webcam-cuerpo {
  grid-column: 1; grid-row: 2;
  min-height: 0;
  min-width: 0;
}
/* `cover`, no `contain`: recorta un pelo por los lados antes que
   dejar bandas negras. Un directo se ve lleno o no se ve. */
.webcam-flotante.grande .webcam-video { object-fit: cover; }
.webcam-flotante.grande .webcam-confirm-txt { font-size: 13.5px; }

.webcam-chat {
  grid-column: 2;
  grid-row: 2;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  border-left: 1px solid var(--borde);
  /* Mismo cristal que las ventanas del escritorio: es una parte más
     de la interfaz, no un recuadro pegado encima. */
  background: linear-gradient(180deg, rgba(20,25,38,.96), rgba(13,16,25,.97));
}
.webcam-chat-hilo {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 11px 12px;
  font-size: 11.5px;
  /* Se lee de abajo arriba, como cualquier chat en vivo */
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
/* El hilo copiado va más apretado que el original: aquí es una
   columna estrecha de acompañamiento, no la conversación principal. */
.webcam-chat-hilo .dis-msg { margin-bottom: 7px; }
.webcam-chat-hilo .dis-avatar, .webcam-chat-hilo .dc-avatar { width: 22px; height: 22px; }
.webcam-chat-hilo .burbuja, .webcam-chat-hilo .dis-txt { font-size: 12px; line-height: 1.45; }
/* Las fotos y vídeos que hayan salido en el hilo no se repiten aquí:
   el sitio es para leer lo que se dice mientras miras la cámara. */
.webcam-chat-hilo .foto-cont,
.webcam-chat-hilo .video-cont,
.webcam-chat-hilo .media-slot { display: none; }

.webcam-chat-ops {
  flex: 0 0 auto;
  max-height: 58%;
  overflow-y: auto;
  padding: 9px 10px 11px;
  border-top: 1px solid var(--borde);
  background: rgba(0,0,0,.22);
}
/* Las opciones son EL MISMO elemento que en Kord, así que heredan su
   estilo; aquí solo se aprietan para que quepan en la columna. */
.webcam-chat-ops .opciones { gap: 6px; }
.webcam-chat-ops .opcion { font-size: 11.5px; padding: 7px 10px; }

/* Sin sitio para las dos columnas, el chat se va DEBAJO del vídeo.

   `minmax(190px, ...)` en su fila es lo importante: antes la fila del
   vídeo se lo comía todo y al chat le quedaban 95 px, o sea dos
   líneas y ningún botón. Un chat de 95 px no es una fusión, es un
   estorbo. Ahora el suelo es del chat y quien se encoge es el vídeo. */
/* Solo por debajo de 880 se apila: hasta ahí caben las dos columnas
   y el formato de stream se mantiene, que es el que se entiende. */
@media (max-width: 880px) {
  .webcam-flotante.grande {
    width: calc(100vw - 24px);
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) minmax(180px, 38vh);
  }
  .webcam-flotante.grande .webcam-cuerpo { grid-column: 1; grid-row: 2; }
  .webcam-chat {
    grid-column: 1; grid-row: 3;
    border-left: none;
    border-top: 1px solid var(--borde);
  }
}

/* PLEGADA
   Se queda solo la barra: el LIVE sigue parpadeando, así que se ve
   que el directo continúa aunque no lo estés mirando. El vídeo NO se
   destruye ni se pausa (sigue corriendo detrás), porque los tiempos
   del guion están medidos contra el metraje real. */
.webcam-flotante.minimizada { width: 190px; }
.webcam-flotante.minimizada .webcam-cuerpo { display: none; }
.webcam-flotante.minimizada .webcam-barra  { cursor: pointer; }
.webcam-flotante.minimizada .webcam-tit {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  opacity: .6;
}

/* CONFIRMACIÓN AL CERRAR
   Cerrar la cámara aquí no es "ocultar una ventana": es irse de la
   escena. Se pregunta encima del propio vídeo para que quede claro
   qué es lo que estás cerrando. */
.webcam-confirm {
  position: absolute;
  inset: 0;          /* del .webcam-cuerpo, que es su padre relativo */
  z-index: 3;        /* por encima del aviso de guardado en el Vault */
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 12px;
  padding: 16px;
  background: rgba(6, 8, 13, .92);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  animation: aparecer .18s ease-out;
}
.webcam-confirm-txt {
  margin: 0;
  font-family: var(--fuente-texto);
  font-size: 12px;
  line-height: 1.45;
  color: var(--texto);
  text-align: center;
}
.webcam-confirm-acc { display: flex; gap: 8px; }
.webcam-btn {
  flex: 1;
  padding: 8px 10px;
  border-radius: var(--radio);
  font-family: var(--fuente-ui);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
/* Quedarse es la opción por defecto: es la que lleva a algo. */
.webcam-btn.seguir {
  border: 1px solid rgb(var(--rgb-carmesi) / .55);
  background: linear-gradient(135deg, var(--acento-carmesi), #ff4d6d);
  color: #fff;
  box-shadow: 0 0 16px rgb(var(--rgb-carmesi) / .35);
}
.webcam-btn.seguir:hover { box-shadow: 0 0 22px rgb(var(--rgb-carmesi) / .55); }
/* Saltar existe, se ve y se entiende, pero no se vende. */
.webcam-btn.salir {
  border: 1px solid var(--borde);
  background: transparent;
  color: var(--texto-tenue);
}
.webcam-btn.salir:hover { border-color: var(--borde-fuerte); color: var(--texto); }

.webcam-cuerpo {
  aspect-ratio: 4 / 3;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.webcam-video { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Confirmacion de guardado dentro de la ventana de camara.
   El aviso reutiliza .audio-nuevo (el mismo del hilo), pero aqui va
   sobre el video, asi que necesita fondo para leerse. */
.webcam-cuerpo { position: relative; }
.webcam-cuerpo .audio-nuevo {
  position: absolute;
  left: 8px;
  bottom: 8px;
  margin: 0;
  padding: 4px 9px;
  border-radius: var(--radio-capsula);
  background: rgba(4, 35, 26, .82);
  border: 1px solid rgb(var(--rgb-esmeralda) / .45);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: aparecer .3s ease-out;
}

.webcam-cuerpo .media-slot {
  border: none;
  background: transparent;
  min-width: 0;
}

/* --- Visor a pantalla completa --- */
.lightbox {
  position: absolute;
  inset: 0;
  background: rgba(3,5,8,.94);
  z-index: 9000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 30px;
  cursor: zoom-out;
  animation: aparecer .2s ease-out;
}
.lightbox img, .lightbox video { max-width: 100%; max-height: 82%; object-fit: contain; border-radius: 4px; }
.lightbox-falta {
  color: var(--texto-tenue);
  font-family: ui-monospace, Consolas, monospace;
  font-size: 12px;
  white-space: pre-line;
  text-align: center;
}
.lightbox-pie {
  color: var(--texto);
  font-size: 13px;
  text-align: center;
  max-width: 560px;
  line-height: 1.6;
}

/* --- Opciones de decisión ---
   PRIORIDAD VISUAL ABSOLUTA: las respuestas del jugador se ven
   SIEMPRE completas, sin scroll, sea cual sea el número (2, 3 o 4).

   Cómo se garantiza:
   · Este bloque NO se encoge (flex-shrink: 0) y toma su altura
     natural: crece hacia arriba según cuántas opciones haya.
   · El historial (.hilo, flex: 1 1 0 + min-height: 0) es lo único
     que cede espacio y scrollea. Si hacen falta, las opciones
     empujan el historial hacia arriba hasta reducirlo.
   · SIN max-height y SIN overflow aquí: nada puede recortar u
     ocultar una opción tras un scroll.
   · Si hay muchas opciones, se compactan (menos padding y fuente)
     para que quepan enteras en pantalla en vez de recortarse. */
.opciones {
  flex: 0 0 auto;
  border-top: 1px solid var(--borde);
  padding: 9px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--panel);
}

.opcion {
  background: var(--panel-alto);
  border: 1px solid var(--borde);
  color: var(--texto);
  padding: 8px 12px;
  border-radius: var(--radio);
  text-align: left;
  font-size: 12.5px;
  line-height: 1.35;
  display: flex;
  align-items: center;
  gap: 10px;
  transition: border-color .15s, background .15s;
}

/* A más opciones, botones más compactos (siguen legibles) para que
   el conjunto entero quepa sin scroll. */
.opciones:has(.opcion:nth-child(3)) { gap: 5px; }
.opciones:has(.opcion:nth-child(3)) .opcion {
  padding: 7px 11px;
  font-size: 12px;
  line-height: 1.3;
}
.opciones:has(.opcion:nth-child(4)) .opcion {
  padding: 6px 11px;
  font-size: 11.5px;
  line-height: 1.25;
}
.opcion:hover:not(.bloqueada) { border-color: var(--acento); background: #2d3446; }

.opcion-txt { flex: 1; }

/* Coste de atención: el jugador debe verlo ANTES de pulsar */
.opcion-coste {
  font-size: 12px;
  color: var(--acento-suave);
  letter-spacing: 1px;
  flex: 0 0 auto;
}

.opcion.bloqueada {
  opacity: .4;
  cursor: not-allowed;
  border-style: dashed;
}
.opcion-motivo {
  font-size: 10px;
  color: var(--texto-tenue);
  font-style: italic;
  flex: 0 0 auto;
}

.fin-hilo {
  font-size: 11px;
  color: var(--texto-tenue);
  font-style: italic;
  text-align: center;
  padding: 4px;
}

/* =========================================================
   2. KORD — el Discord falso
   ========================================================= */
.app-kord {
  display: flex;
  width: 100%;
  background: #313338;
  color: #dbdee1;
}

/* --- Rail de servidores (izquierda del todo) --- */
.kord-rail {
  width: 60px;
  flex: 0 0 auto;
  background: #1e1f22;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 10px 0;
}
.kord-serv, .kord-serv-mas {
  width: 44px; height: 44px;
  border: none;
  padding: 0;
  border-radius: 16px;
  background: #313338;
  color: #23a559;
  font-size: 22px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: border-radius .15s;
}
.kord-serv:hover, .kord-serv-mas:hover { border-radius: 13px; }
.kord-serv .dc-avatar.serv { width: 44px; height: 44px; border-radius: inherit; background: #5865f2; }
.kord-serv .dc-avatar.serv .dc-avatar-img { border-radius: inherit; }

/* --- Columna de canales --- */
.kord-cols {
  width: 212px;
  flex: 0 0 auto;
  background: #2b2d31;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.kord-serv-nom {
  padding: 13px 16px;
  font-size: 14px;
  font-weight: 700;
  color: #f2f3f5;
  border-bottom: 1px solid rgba(0,0,0,.3);
  box-shadow: 0 1px 0 rgba(0,0,0,.2);
  flex: 0 0 auto;
}
.kord-canales { flex: 1; overflow-y: auto; padding: 8px; }
.kord-cat {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .4px;
  text-transform: uppercase;
  color: #949ba4;
  padding: 14px 8px 4px;
}
.kord-canal {
  display: flex; align-items: center; gap: 6px;
  width: 100%;
  background: transparent; border: none;
  color: #949ba4;
  padding: 6px 8px;
  border-radius: 4px;
  font-size: 15px;
  text-align: left;
  cursor: pointer;
  margin-bottom: 1px;
}
.kord-canal-ic  { width: 20px; flex: 0 0 auto; text-align: center; color: #80848e; }
.kord-canal-nom { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kord-canal:hover  { background: rgba(255,255,255,.04); color: #dbdee1; }
.kord-canal.activo { background: rgba(255,255,255,.08); color: #f2f3f5; }
.kord-canal-coste  { font-size: 10px; color: #dc9a3c; margin-left: auto; flex: 0 0 auto; }

/* barra de usuario propio, abajo */
.kord-yo {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px;
  background: #232428;
  flex: 0 0 auto;
}
.kord-yo-nom { font-size: 13px; font-weight: 600; color: #f2f3f5; }

/* --- Chat central --- */
.kord-chat {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: #313338;
}
.kord-chat-cab {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px;
  border-bottom: 1px solid rgba(0,0,0,.25);
  box-shadow: 0 1px 0 rgba(0,0,0,.15);
  flex: 0 0 auto;
}
.kord-chat-cab-ic  { color: #80848e; font-size: 18px; }
.kord-chat-cab-nom { font-size: 15px; font-weight: 700; color: #f2f3f5; }
.kord-chat-cuerpo  { flex: 1; display: flex; flex-direction: column; min-height: 0; }

/* --- Lista de miembros (derecha) --- */
.kord-miembros {
  width: 210px;
  flex: 0 0 auto;
  background: #2b2d31;
  overflow-y: auto;
  padding: 10px 8px;
}
.kord-rol {
  font-size: 11px; font-weight: 700; letter-spacing: .4px;
  text-transform: uppercase; color: #949ba4;
  padding: 16px 8px 4px;
}
.kord-miembro {
  display: flex; align-items: center; gap: 10px;
  padding: 4px 8px;
  border-radius: 4px;
}
.kord-miembro:hover { background: rgba(255,255,255,.04); }
.kord-miembro-nom {
  font-size: 14px; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kord-miembro.off { opacity: .4; }

/* --- Avatares (compartido: mensajes + miembros) --- */
.dc-avatar {
  position: relative;
  width: 40px; height: 40px;
  border-radius: 50%;
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: var(--c, #5865f2);
}
.dc-avatar.sm { width: 32px; height: 32px; }
.dc-avatar-img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; display: block; }
.dc-avatar-ini { color: #fff; font-weight: 700; font-size: 15px; line-height: 1; }
.dc-avatar.sm .dc-avatar-ini { font-size: 13px; }
/* LED de presencia: no es un punto plano, es un diodo encendido.
   De un vistazo sabes quién está despierto a las 3 AM. */
.dc-estado {
  position: absolute; right: -3px; bottom: -3px;
  width: 10px; height: 10px; border-radius: 50%;
  border: 3px solid #2b2d31; box-sizing: content-box;
  transition: box-shadow .3s ease;
}
.dc-estado.linea {
  background: radial-gradient(circle at 35% 30%, #4ade80, #23a559 70%);
  box-shadow: 0 0 8px rgba(35,165,89,.9);
}
.dc-estado.ausente {
  background: radial-gradient(circle at 35% 30%, #fcd34d, var(--acento-ambar) 70%);
  box-shadow: 0 0 8px rgb(var(--rgb-ambar) / .75);
}
.dc-estado.ocupado {
  background: radial-gradient(circle at 35% 30%, #ff6b7f, var(--acento-carmesi) 70%);
  box-shadow: 0 0 8px rgb(var(--rgb-carmesi) / .8);
}
.dc-estado.desconectado { background: #4b505c; box-shadow: none; }
/* El miembro apagado no debe competir con los que están en línea */
.kord-miembro.off .dc-estado { box-shadow: none; }

/* --- Mensaje estilo Discord --- */
.hilo.estilo-kord-discord { padding: 12px 0; gap: 0; }
.dc-msg {
  display: flex;
  gap: 14px;
  padding: 1px 16px;
  margin-top: 14px;
  animation: aparecer .2s ease-out;
}
.dc-msg.agrupado { margin-top: 1px; }
.dc-msg-av   { width: 40px; flex: 0 0 auto; }
.dc-msg-body { flex: 1; min-width: 0; }
.dc-msg-cab  { display: flex; align-items: baseline; gap: 8px; margin-bottom: 1px; }
.dc-msg-nom  { font-size: 15px; font-weight: 600; color: #f2f3f5; }
.dc-msg-hora { font-size: 11px; color: #949ba4; }
.dc-msg-texto {
  font-size: 15px; line-height: 1.375; color: #dbdee1;
  white-space: pre-wrap; word-wrap: break-word;
}
.dc-msg .dc-estado { display: none; }         /* en mensajes no va el punto */
.dc-msg-media { margin-top: 4px; max-width: 340px; }
.dc-sistema {
  text-align: center; font-size: 12px; color: #949ba4;
  padding: 10px 16px; font-style: italic;
}

/* Opciones de Matt integradas en el tema oscuro de Kord */
.app-kord .opciones { background: #313338; border-top-color: rgba(0,0,0,.25); }
.app-kord .opcion   { background: #3a3d44; border-color: rgba(0,0,0,.2); color: #dbdee1; }
.app-kord .opcion:hover:not(.bloqueada) { background: #41454d; border-color: #5865f2; }

/* =========================================================
   3. WISP — la mensajería
   ========================================================= */
/* ---- Tema WhatsApp Web (oscuro) ---- */
.app-wisp {
  display: flex;
  width: 100%;
  background: #0b141a;
  color: #e9edef;
  --wa-verde: #00a884;
  --wa-panel: #111b21;
  --wa-barra: #202c33;
  --wa-hover: #202c33;
  --wa-activo: #2a3942;
  --wa-tenue: #8696a0;
  --wa-check: #53bdeb;
}

/* ================= LATERAL ================= */
.wisp-lateral {
  width: 300px;
  flex: 0 0 auto;
  border-right: 1px solid rgba(134,150,160,.15);
  display: flex;
  flex-direction: column;
  background: var(--wa-panel);
  min-height: 0;
}

/* Cabecera de Matt + boton de Estados 24h */
.wisp-yo {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px;
  background: var(--wa-barra);
  flex: 0 0 auto;
}
.wisp-yo-nom { font-size: 14px; font-weight: 600; flex: 1; }
.wisp-estados-btn {
  position: relative;
  background: transparent; border: none;
  color: var(--wa-tenue);
  font-size: 12px; cursor: pointer;
  padding: 6px 10px; border-radius: 16px;
}
.wisp-estados-btn:hover { background: rgba(255,255,255,.06); color: #e9edef; }
.wisp-estados-punto {
  position: absolute; top: -2px; right: -2px;
  background: var(--wa-verde); color: #0b141a;
  font-size: 10px; font-weight: 700;
  min-width: 16px; height: 16px; border-radius: 9px;
  display: grid; place-items: center; padding: 0 4px;
}

/* Buscador */
.wisp-buscador { padding: 8px 12px; flex: 0 0 auto; }
.wisp-buscar-input {
  width: 100%;
  background: var(--wa-barra);
  border: none; outline: none;
  color: #e9edef;
  font-size: 13px;
  padding: 8px 14px;
  border-radius: 8px;
}
.wisp-buscar-input::placeholder { color: var(--wa-tenue); }

/* Lista de chats */
.wisp-contactos { flex: 1; overflow-y: auto; min-height: 0; }
.wisp-contacto {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  background: transparent; border: none;
  border-bottom: 1px solid rgba(134,150,160,.10);
  padding: 10px 14px;
  text-align: left;
  color: #e9edef;
  cursor: pointer;
}
.wisp-contacto:hover  { background: var(--wa-hover); }
.wisp-contacto.activo { background: var(--wa-activo); }

.wisp-c-centro { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.wisp-c-fila { display: flex; align-items: center; gap: 8px; }
.wisp-c-nom {
  flex: 1; font-size: 14px; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wisp-c-hora { font-size: 11px; color: var(--wa-tenue); flex: 0 0 auto; }
.wisp-c-prev {
  flex: 1; font-size: 12.5px; color: var(--wa-tenue);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wisp-c-badge {
  flex: 0 0 auto;
  background: var(--wa-verde); color: #0b141a;
  font-size: 11px; font-weight: 700;
  min-width: 19px; height: 19px; border-radius: 10px;
  display: grid; place-items: center; padding: 0 5px;
}
.wisp-vacio { font-size: 12.5px; color: var(--wa-tenue); font-style: italic; padding: 16px; }

/* ================= CHAT ================= */
.wisp-main { flex: 1; display: flex; flex-direction: column; min-width: 0; background: #0b141a; }
.wisp-cabecera {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 16px;
  background: var(--wa-barra);
  border-bottom: 1px solid rgba(134,150,160,.15);
  flex: 0 0 auto;
  min-height: 40px;
}
.wisp-cab-info { min-width: 0; }
.wisp-nombre { font-size: 15px; font-weight: 600; }
.wisp-estado-txt { font-size: 12px; color: var(--wa-tenue); display: flex; align-items: center; gap: 5px; }

/* ---------- "escribiendo…" DENTRO del hilo ----------
   Burbuja con tres puntos en el sitio exacto donde va a caer el
   mensaje. Hereda el aspecto de `.burbuja.suya`, así que se adapta
   sola al tema de cada app (Wisp verde, Kord azul...).
   La pinta src/apps/_chat-ui.js y la controla core/dialogue.js. */
.escribiendo-burbuja {
  display: inline-flex !important;
  align-items: center;
  gap: 4px;
  padding: 11px 14px !important;
  min-height: 0;
  animation: escribiendoEntra .22s ease-out;
}
@keyframes escribiendoEntra {
  from { opacity: 0; transform: translateY(4px) scale(.96); }
  to   { opacity: 1; transform: none; }
}
.escribiendo-puntos { display: inline-flex; gap: 4px; align-items: center; }
.escribiendo-puntos i {
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
  opacity: .3;
  animation: escribiendoPunto 1.25s infinite;
}
.escribiendo-puntos i:nth-child(2) { animation-delay: .18s; }
.escribiendo-puntos i:nth-child(3) { animation-delay: .36s; }
@keyframes escribiendoPunto {
  0%, 60%, 100% { opacity: .28; transform: translateY(0); }
  30%           { opacity: .95; transform: translateY(-2px); }
}

/* "escribiendo..." con puntos animados */
.wisp-puntos { display: inline-flex; gap: 3px; align-items: center; }
.wisp-puntos i {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--wa-tenue);
  animation: wispPunto 1.2s infinite;
}
.wisp-puntos i:nth-child(2) { animation-delay: .2s; }
.wisp-puntos i:nth-child(3) { animation-delay: .4s; }
@keyframes wispPunto { 0%,60%,100% { opacity:.25 } 30% { opacity:1 } }

.wisp-cuerpo { flex: 1; display: flex; flex-direction: column; min-height: 0; }

/* Fondo del hilo + scroll discreto */
.hilo.estilo-wisp {
  background:
    radial-gradient(circle at 20% 10%, rgba(0,168,132,.05), transparent 40%),
    #0b141a;
  scrollbar-width: thin;
  scrollbar-color: rgba(134,150,160,.35) transparent;
}
.hilo.estilo-wisp::-webkit-scrollbar { width: 7px; }
.hilo.estilo-wisp::-webkit-scrollbar-thumb { background: rgba(134,150,160,.3); border-radius: 8px; }
.hilo.estilo-wisp::-webkit-scrollbar-track { background: transparent; }

/* Burbujas: recibidas oscuras a la izquierda, enviadas verdes a la derecha */
.estilo-wisp .burbuja { box-shadow: 0 1px 1px rgba(0,0,0,.25); }
.estilo-wisp .burbuja.suya { background: var(--wa-barra); color: #e9edef; }
.estilo-wisp .burbuja.mia  { background: #005c4b; color: #e9edef; }

/* Pie de burbuja: hora + doble check azul */
.burbuja-meta {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 4px; margin-top: 2px;
}
.burbuja-hora { font-size: 10px; color: rgba(233,237,239,.55); }
.burbuja-check { font-size: 11px; color: var(--wa-check); letter-spacing: -1px; }

/* Bienvenida (sin chat abierto) */
.wisp-bienvenida {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 8px;
  color: var(--wa-tenue); text-align: center; padding: 30px;
}
.wisp-bv-ico { font-size: 46px; opacity: .5; }
.wisp-bv-t { font-size: 20px; color: #e9edef; }
.wisp-bv-p { font-size: 13px; }

/* Opciones de Matt integradas en el tema */
.app-wisp .opciones { background: var(--wa-barra); border-top-color: rgba(134,150,160,.15); }
.app-wisp .opcion {
  background: #2a3942; border-color: rgba(134,150,160,.18); color: #e9edef;
}
.app-wisp .opcion:hover:not(.bloqueada) { background: #33444d; border-color: var(--wa-verde); }

/* ============ NOTA DE VOZ (onda + progreso) ============ */
.audio-centro { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
/* Onda digital: barras finas de vúmetro. La zona ya escuchada se
   tiñe de esmeralda con un filo de luz en el cabezal de lectura. */
.audio-onda {
  position: relative;
  display: flex; align-items: center; gap: 2px;
  height: 24px; overflow: hidden;
}
.audio-onda span {
  flex: 1; min-width: 2px;
  background: linear-gradient(180deg, rgba(233,237,239,.50), rgba(233,237,239,.26));
  border-radius: 2px;
}
.audio-prog {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 0%;
  background: linear-gradient(90deg, rgb(var(--rgb-esmeralda) / .42), rgba(52,211,153,.24));
  /* Cabezal de lectura: la línea vertical que va avanzando */
  border-right: 1px solid rgba(52,211,153,.9);
  box-shadow: 0 0 12px rgb(var(--rgb-esmeralda) / .55);
  border-radius: 3px 1px 1px 3px;
  transition: width .1s linear;
  pointer-events: none;
}
.burbuja.mia .audio-prog {
  background: linear-gradient(90deg, rgba(255,255,255,.30), rgba(255,255,255,.14));
  border-right-color: rgba(255,255,255,.9);
  box-shadow: 0 0 12px rgba(255,255,255,.45);
}
.audio-dur {
  font-family: var(--fuente-mono);
  font-size: 10px;
  letter-spacing: .3px;
  color: rgba(233,237,239,.55);
}

/* ============ ESTADOS 24h (STORIES) ============ */
.wisp-panel-estados {
  position: absolute;
  top: 46px; left: 14px;
  width: 300px;
  background: #202c33;
  border: 1px solid rgba(134,150,160,.2);
  border-radius: 10px;
  box-shadow: 0 16px 40px rgba(0,0,0,.55);
  z-index: 70;
  animation: aparecer .18s ease-out;
}
.wisp-pe-cab {
  display: flex; align-items: center;
  padding: 10px 12px;
  font-size: 12px; font-weight: 600; color: #e9edef;
  border-bottom: 1px solid rgba(134,150,160,.15);
}
.wisp-pe-cab span { flex: 1; }
.wisp-pe-cerrar {
  background: none; border: none; color: #8696a0;
  font-size: 18px; line-height: 1; cursor: pointer;
}
.wisp-pe-fila { display: flex; gap: 12px; padding: 14px 12px; overflow-x: auto; }
.wisp-pe-item {
  background: none; border: none; padding: 0; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  flex: 0 0 auto; width: 62px;
}
/* Anillo verde = estado nuevo sin ver. Es lo que pica para abrirlo. */
.wisp-pe-aro {
  padding: 2px; border-radius: 50%;
  background: linear-gradient(135deg, #00a884, #25d366);
}
.wisp-pe-item.visto .wisp-pe-aro { background: rgba(134,150,160,.35); opacity: .6; }
.wisp-pe-nom {
  font-size: 10px; color: #8696a0; max-width: 62px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wisp-pe-vacio { font-size: 12px; color: #8696a0; font-style: italic; padding: 4px; }

/* ---------------------------------------------------------
   VISOR DE ESTADO 24h
   ---------------------------------------------------------
   Antes la imagen iba a pelo y se desbordaba, con el avatar y el
   texto flotando encima sin fondo: sobre una foto clara el pie no
   se leía. Ahora es una tarjeta con proporción de historia, el
   medio contenido (nunca recortado) y degradados arriba y abajo
   para que cabecera y pie se lean sobre cualquier imagen.
   --------------------------------------------------------- */
.wisp-visor {
  position: absolute;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  padding: 18px;
  background: rgba(4, 8, 11, .82);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  animation: aparecer .2s ease-out;
}

/* Proporción 9/16 como cualquier historia, pero sin pasarse del
   alto disponible: manda lo que sea más pequeño. */
.wisp-visor-caja {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(100%, calc((100vh - 120px) * 0.5625), 380px);
  height: min(100%, 640px);
  border-radius: 14px;
  overflow: hidden;
  background: #05080a;
  box-shadow: 0 24px 70px rgba(0,0,0,.7), 0 0 0 1px rgba(255,255,255,.08);
  animation: estadoEntra .26s cubic-bezier(.2,.8,.2,1);
}
@keyframes estadoEntra {
  from { opacity: 0; transform: scale(.97) translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* --- Barra de progreso --- */
.wisp-visor-barra {
  position: absolute;
  top: 10px; left: 12px; right: 12px;
  height: 3px;
  border-radius: 3px;
  background: rgba(255,255,255,.28);
  overflow: hidden;
  z-index: 3;
}
.wisp-visor-prog {
  height: 100%;
  width: 0;
  border-radius: 3px;
  background: #fff;
  animation: estadoProgreso linear forwards;
}
@keyframes estadoProgreso { from { width: 0; } to { width: 100%; } }

/* --- Cabecera --- */
.wisp-visor-cab {
  position: absolute;
  top: 20px; left: 0; right: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  z-index: 3;
  /* Velo para que el nombre se lea sobre fotos claras */
  background: linear-gradient(180deg, rgba(0,0,0,.62), transparent);
}
.wisp-visor-quien { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.wisp-visor-nom {
  font-family: var(--fuente-ui);
  font-size: 14.5px;
  font-weight: 600;
  /* Tracking negativo en los titulares: es lo que separa una
     tipografía de interfaz actual de una de 2012. */
  letter-spacing: -.25px;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0,0,0,.55);
}
.wisp-visor-hora {
  font-family: var(--fuente-texto);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .1px;
  color: rgba(255,255,255,.62);
  text-shadow: 0 1px 3px rgba(0,0,0,.55);
}
.wisp-visor-cerrar {
  flex: none;
  background: none;
  border: none;
  color: #fff;
  font-size: 24px;
  line-height: 1;
  padding: 0 4px;
  opacity: .85;
  text-shadow: 0 1px 6px rgba(0,0,0,.8);
}
.wisp-visor-cerrar:hover { opacity: 1; }

/* --- El medio: contenido, nunca recortado ni desbordado --- */
.wisp-visor-medio {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #05080a;
}
.wisp-visor-slot {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.wisp-visor-slot img,
.wisp-visor-slot video {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
}
.wisp-visor-slot .media-slot { min-width: 0; margin: 16px; }

/* --- Pie: texto y like sobre degradado --- */
.wisp-visor-pie {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 3;
  padding: 34px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: linear-gradient(0deg, rgba(0,0,0,.88) 35%, transparent);
}
.wisp-visor-txt {
  margin: 0;
  font-family: var(--fuente-texto);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: -.1px;
  color: rgba(255,255,255,.94);
  /* La sombra dura hacía el texto sucio: el degradado del pie ya
     hace el contraste, así que aquí solo hace falta un apoyo. */
  text-shadow: 0 1px 3px rgba(0,0,0,.55);
  /* Reparte las líneas para que no quede una palabra suelta */
  text-wrap: pretty;
  user-select: text;
  /* Un pie muy largo no puede comerse la foto entera */
  max-height: 5.6em;
  overflow-y: auto;
}

.wisp-visor-acciones { display: flex; align-items: center; gap: 9px; }

.wisp-like {
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.22);
  background: rgba(255,255,255,.08);
  color: rgba(255,255,255,.85);
  font-size: 16px;
  line-height: 1;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: transform .16s cubic-bezier(.2,.8,.2,1),
              background .18s ease, border-color .18s ease, color .18s ease;
}
.wisp-like:hover { transform: scale(1.1); border-color: rgb(var(--rgb-carmesi) / .6); color: #ff8fa3; }
.wisp-like.dado {
  color: #fff;
  background: linear-gradient(135deg, var(--acento-carmesi), #ff4d6d);
  border-color: transparent;
  box-shadow: 0 0 16px rgb(var(--rgb-carmesi) / .6);
}
/* Latido al darle: el gesto tiene que sentirse */
.wisp-like.late { animation: likeLatido .45s cubic-bezier(.2,.8,.2,1); }
@keyframes likeLatido {
  0%, 100% { transform: scale(1); }
  35%      { transform: scale(1.35); }
  65%      { transform: scale(.94); }
}

.wisp-like-num {
  /* Con la de interfaz, no la mono: el mono es para el HUD del
     sistema (reloj, atención), no para el contador de una app. */
  font-family: var(--fuente-ui);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -.1px;
  font-variant-numeric: tabular-nums;
  color: rgba(255,255,255,.82);
  text-shadow: 0 1px 3px rgba(0,0,0,.55);
}

/* =========================================================
   3b. GLIM — el Instagram falso (tema oscuro)
   ========================================================= */
.app-glim {
  flex-direction: column;
  width: 100%;
  background: #000;
  color: #f5f5f5;
  --ig-borde: #262626;
  --ig-panel: #121212;
  --ig-tenue: #a8a8a8;
  --ig-azul: #0095f6;
}

/* ---- Barra de navegación superior ---- */
.gl-nav {
  display: flex; align-items: center; gap: 16px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--ig-borde);
  background: #000;
  flex: 0 0 auto;
}
.gl-logo {
  font-size: 20px; font-weight: 700; letter-spacing: -.5px;
  background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  flex: 0 0 auto;
}
.gl-tabs { display: flex; gap: 4px; margin-left: auto; }
.gl-tab {
  position: relative;
  display: flex; align-items: center; gap: 7px;
  background: transparent; border: none;
  color: var(--ig-tenue);
  padding: 8px 14px; border-radius: 8px;
  font-size: 13px; cursor: pointer;
}
.gl-tab:hover  { background: #1a1a1a; color: #f5f5f5; }
.gl-tab.activo { color: #f5f5f5; font-weight: 700; background: #1a1a1a; }
.gl-tab-ico { font-size: 15px; }
.gl-badge {
  background: #ff3040; color: #fff;
  font-size: 10px; font-weight: 700;
  min-width: 16px; height: 16px; border-radius: 9px;
  display: grid; place-items: center; padding: 0 4px;
}

.gl-cuerpo { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.gl-nada { color: var(--ig-tenue); font-style: italic; font-size: 12.5px; padding: 20px; }

/* =========================================================
   PESTAÑA 1 — INICIO
   ========================================================= */
.gl-inicio { overflow-y: auto; align-items: center; }

/* ---- Historias ---- */
.gl-historias {
  display: flex; gap: 16px;
  width: 100%; max-width: 540px;
  padding: 16px;
  overflow-x: auto;
  border-bottom: 1px solid var(--ig-borde);
  flex: 0 0 auto;
}
.gl-hist {
  background: none; border: none; padding: 0; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  flex: 0 0 auto; width: 70px;
}
/* Aro con gradiente = historia sin ver */
.gl-hist-aro {
  padding: 3px; border-radius: 50%;
  background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888);
}
.gl-hist-aro .dc-avatar { border: 2px solid #000; }
.gl-hist.vista .gl-hist-aro { background: #363636; }
.gl-hist-nom {
  font-size: 11px; color: var(--ig-tenue);
  max-width: 70px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---- Feed ---- */
.gl-feed { width: 100%; max-width: 540px; padding: 16px 0 30px; }
.gl-post {
  border: 1px solid var(--ig-borde);
  border-radius: 10px;
  background: #000;
  margin-bottom: 22px;
  overflow: hidden;
}
.gl-post-cab { display: flex; align-items: center; gap: 11px; padding: 11px 13px; }
.gl-post-info { flex: 1; min-width: 0; }
.gl-post-nom { font-size: 13.5px; font-weight: 600; }
.gl-post-ubi { font-size: 11px; color: var(--ig-tenue); }

/* Insignia de cuenta verificada */
.gl-verificado {
  display: inline-grid; place-items: center;
  width: 13px; height: 13px; margin-left: 5px;
  border-radius: 50%;
  background: #0095f6; color: #fff;
  font-size: 8px; font-weight: 700;
  vertical-align: middle;
}

/* Las conversaciones secundarias son ruido de fondo: se ven algo
   más apagadas para que las de la trama destaquen. */
.gl-dm-item.secundaria .gl-dm-nom  { font-weight: 500; color: #d0d0d0; }
.gl-dm-item.secundaria .dc-avatar  { opacity: .82; }

/* Chat con algo SIN LEER: sube arriba de la lista (ver pintarListaDMs)
   y se marca como en Instagram, con nombre y vista previa en blanco y
   un punto. Gana también a lo apagado de las secundarias: si te ha
   escrito, ya no es ruido de fondo. */
.gl-dm-item.nuevo .gl-dm-nom,
.gl-dm-item.secundaria.nuevo .gl-dm-nom { color: #fff; font-weight: 700; }
.gl-dm-item.nuevo .gl-dm-prev          { color: #f5f5f5; font-weight: 600; }
.gl-dm-item.secundaria.nuevo .dc-avatar { opacity: 1; }
.gl-dm-punto {
  flex: 0 0 auto;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--acento-magenta, #d946ef);
  box-shadow: 0 0 8px rgb(217 70 239 / .75);
}
.gl-post-mas { color: var(--ig-tenue); letter-spacing: 1px; }

.gl-post-marco { background: #0a0a0a; }
.gl-slot { display: block; width: 100%; }
.gl-slot img { display: block; width: 100%; cursor: zoom-in; }
.gl-slot .media-slot {
  border-radius: 0; border-left: none; border-right: none;
  min-height: 260px; justify-content: center;
}

/* Acciones */
.gl-acciones { display: flex; align-items: center; gap: 14px; padding: 10px 13px 6px; }
/* Guardar se va a la derecha del todo, como en Instagram */
.gl-guardar { margin-left: auto; }
.gl-guardar.hecho { filter: none; opacity: 1; transform: scale(1.05); }
.gl-guardar:not(.hecho) { filter: grayscale(1); opacity: .55; }

/* Los "me gusta" en su propia línea, en negrita, encima del texto */
.gl-likes {
  font-size: 13px;
  font-weight: 600;
  color: #f5f5f5;
  margin-bottom: 5px;
}

/* "Ver los N comentarios" */
.gl-ver-com {
  font-size: 12.5px;
  color: var(--ig-tenue);
  margin: 5px 0 2px;
  cursor: default;
}

/* Cuándo se publicó: el cierre gris de toda tarjeta */
.gl-post-hace {
  margin-top: 8px;
  font-size: 10.5px;
  letter-spacing: .3px;
  text-transform: uppercase;
  color: #6e6e6e;
}

/* El corazón del doble clic: sale grande, late y se va */
.gl-post-marco { position: relative; }
.gl-burbuja-corazon {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 84px;
  color: #fff;
  text-shadow: 0 4px 24px rgba(0,0,0,.5);
  pointer-events: none;
  animation: glCorazon .9s cubic-bezier(.2,1.4,.3,1) forwards;
}
@keyframes glCorazon {
  0%   { opacity: 0; transform: scale(.3); }
  22%  { opacity: 1; transform: scale(1.15); }
  40%  { transform: scale(.97); }
  70%  { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.05); }
}
@media (prefers-reduced-motion: reduce) {
  .gl-burbuja-corazon { animation: aparecer .3s ease-out forwards; }
}
.gl-accion {
  background: none; border: none; cursor: pointer;
  color: #f5f5f5; font-size: 19px; line-height: 1; padding: 0;
  transition: transform .12s, color .12s;
}
.gl-accion:hover { transform: scale(1.12); }
.gl-like.liked { color: #ff3040; }
.gl-likes { font-size: 13px; font-weight: 600; margin-right: auto; }

/* Pie */
.gl-post-pie { padding: 4px 13px 13px; }
.gl-pie-txt { font-size: 13.5px; line-height: 1.45; }
.gl-tags { font-size: 13px; color: #4a9eff; margin-top: 3px; }
.gl-comentarios { margin-top: 8px; display: flex; flex-direction: column; gap: 3px; }
.gl-comentario { font-size: 12.5px; color: var(--ig-tenue); }
.gl-comentario b { color: #f5f5f5; }

/* ---- Visor de historia ---- */
.gl-visor {
  position: absolute;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(0,0,0,.94);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  animation: aparecer .2s ease-out;
}
/* ---------------------------------------------------------
   EL MARCO 9:16
   Se queda con el alto disponible y calcula el ancho a partir de
   ahí, así que siempre es una historia vertical de verdad y no
   una caja que cambia de forma con la ventana.
   --------------------------------------------------------- */
.gl-visor-marco {
  position: relative;
  height: 100%;
  aspect-ratio: 9 / 16;
  max-width: 100%;
  margin: 0 auto;
  overflow: hidden;
  border-radius: 14px;
  background: #000;
  box-shadow: 0 24px 70px rgba(0,0,0,.7);
  isolation: isolate;
}

/* FONDO: la misma foto, ampliada y desenfocada.
   Es lo que hace que valga CUALQUIER proporción: la imagen entra
   entera y sin recortar, y lo que sobra a los lados no es un hueco
   negro sino su propio color. Sin esto, una foto 3:4 deja dos
   franjas muertas y parece que falta algo. */
.gl-visor-fondo {
  position: absolute;
  inset: -8%;                /* de más, para que el desenfoque no deje borde */
  background-size: cover;
  background-position: center;
  /* Bastante luz para que las bandas se lean como COLOR de la foto
     y no como hueco negro. Con brillo bajo, más los velos que caen
     justo encima, el desenfoque se veía negro y no servía de nada. */
  filter: blur(30px) saturate(1.6) brightness(.9);
  z-index: 0;
}

.gl-visor-medio {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.gl-visor-medio .gl-slot,
.gl-visor-medio img,
.gl-visor-medio video {
  width: 100%;
  height: 100%;
  border-radius: 0;
}
/* El envoltorio centra lo que lleve dentro: si no, el recuadro de
   "falta este slot" se queda pegado arriba del marco. */
.gl-visor-medio .gl-slot {
  display: flex;
  align-items: center;
  justify-content: center;
}
.gl-visor-medio img,
.gl-visor-medio video { object-fit: contain; }

/* Velos: sin ellos el texto blanco desaparece sobre una foto clara */
.gl-velo {
  position: absolute; left: 0; right: 0;
  z-index: 2;
  pointer-events: none;
}
/* Justo lo necesario para leer el texto. Más oscuro y se comían el
   fondo desenfocado, que es lo que da color a los bordes. */
.gl-velo.arriba {
  top: 0; height: 108px;
  background: linear-gradient(180deg, rgba(0,0,0,.6), rgba(0,0,0,0));
}
.gl-velo.abajo {
  bottom: 0; height: 165px;
  background: linear-gradient(0deg, rgba(0,0,0,.7), rgba(0,0,0,0));
}

/* ---- Tramos de progreso: uno por historia ---- */
.gl-visor-barra {
  position: absolute;
  top: 10px; left: 10px; right: 10px;
  z-index: 5;
  display: flex;
  gap: 3px;
}
.gl-tramo {
  flex: 1;
  height: 2.5px;
  border-radius: 3px;
  background: rgba(255,255,255,.32);
  overflow: hidden;
}
.gl-tramo i { display: block; height: 100%; width: 0; background: #fff; }
.gl-tramo.hecho i { width: 100%; }
.gl-tramo.activo i { animation: glTramo linear forwards; }
@keyframes glTramo { from { width: 0; } to { width: 100%; } }
/* Sin animaciones: el tramo activo se queda lleno en vez de crecer */
@media (prefers-reduced-motion: reduce) {
  .gl-tramo.activo i { animation: none; width: 100%; }
}

/* ---- Cabecera, encima de la foto ---- */
.gl-visor-cab {
  position: absolute;
  top: 22px; left: 12px; right: 10px;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 9px;
}
.gl-visor-aro {
  flex: 0 0 auto;
  line-height: 0;
  padding: 2px;
  border-radius: 50%;
  background: conic-gradient(from 0deg,
    var(--acento-ambar), #ff5f6d, var(--acento-magenta), #a855f7, var(--acento-ambar));
}
.gl-visor-aro .dc-avatar { border: 2px solid #000; }
.gl-visor-nom {
  font-size: 13.5px;
  font-weight: 600;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0,0,0,.6);
}
.gl-visor-hora {
  flex: 1;
  font-size: 12px;
  color: rgba(255,255,255,.72);
  text-shadow: 0 1px 3px rgba(0,0,0,.6);
}
.gl-visor-cerrar {
  background: none; border: none;
  color: #fff; font-size: 19px; line-height: 1;
  padding: 4px 6px; cursor: pointer;
  text-shadow: 0 1px 4px rgba(0,0,0,.7);
}
.gl-visor-cerrar:hover { opacity: .75; }

/* ---- Zonas de toque: media historia a cada lado ---- */
.gl-zona {
  position: absolute;
  top: 60px; bottom: 110px;
  width: 40%;
  z-index: 4;
  background: transparent;
  border: none;
  cursor: pointer;
}
.gl-zona.izq { left: 0; }
.gl-zona.der { right: 0; }

/* ---- Pie: texto, responder y me gusta ---- */
.gl-visor-pie {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 5;
  padding: 0 14px 14px;
}
/* =========================================================
   TEXTO DE HISTORIA
   ---------------------------------------------------------
   El de antes era un párrafo de 13,5 px centrado: correcto para
   un pie de foto, pero no es lo que se escribe encima de una
   historia. Ahí el texto ES el diseño — grande, apretado, con
   caja de color o con brillo — y por eso se reconoce a un metro.

   Cinco estilos, los mismos que ofrece Instagram al escribir.
   Se eligen desde content/ con `estiloTexto`:

     (nada)      clásica  — titular blanco gordo con sombra
     'resaltado' el texto sobre una caja de color
     'neon'      manuscrita con brillo
     'maquina'   monoespaciada, aire de nota
     'moderna'   mayúsculas muy apretadas

   Aparte va `estilo:`, que son las LETRAS raras (ᴠᴇʀsᴀʟɪᴛᴀs y
   demás) de src/core/texto-estilo.js. Se pueden combinar: una
   cosa es la fuente y otra los caracteres.
   ========================================================= */
.gl-visor-txt {
  margin: 0 0 14px;
  text-align: center;
  color: #fff;
  /* clásica, por defecto */
  font-family: var(--fuente-titular);
  font-size: 21px;
  line-height: 1.25;
  letter-spacing: -.3px;
  text-shadow: 0 2px 10px rgba(0,0,0,.55), 0 1px 3px rgba(0,0,0,.8);
}

/* RESALTADO — la caja de color detrás del texto. `box-decoration-break`
   es lo que hace que cada línea lleve su propia caja con las esquinas
   redondeadas, en vez de un bloque rectangular alrededor de todo. */
.gl-visor-txt.resaltado {
  font-family: var(--fuente-ui);
  font-weight: 800;
  font-size: 19px;
  line-height: 1.55;
  color: #16181d;
  text-shadow: none;
}
.gl-visor-txt.resaltado span {
  background: #fff;
  padding: 3px 10px;
  border-radius: 6px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
/* Variantes de color de la caja, por si una escena pide otro tono */
.gl-visor-txt.resaltado.rosa   span { background: #ff3d71; color: #fff; }
.gl-visor-txt.resaltado.violeta span { background: var(--acento-magenta); color: #fff; }
.gl-visor-txt.resaltado.negro  span { background: rgba(0,0,0,.82); color: #fff; }

/* NEÓN — manuscrita con brillo. La que usan para lo cursi y lo caliente. */
.gl-visor-txt.neon {
  font-family: var(--fuente-manuscrita);
  font-weight: 700;
  font-size: 32px;
  line-height: 1.15;
  letter-spacing: .5px;
  color: #fff;
  text-shadow:
    0 0 6px rgba(255,255,255,.9),
    0 0 18px var(--acento-magenta),
    0 0 34px rgb(var(--rgb-magenta) / .75),
    0 2px 4px rgba(0,0,0,.4);
}

/* MÁQUINA — monoespaciada, aire de nota escrita deprisa */
.gl-visor-txt.maquina {
  font-family: var(--fuente-mono);
  font-weight: 400;
  font-size: 15px;
  line-height: 1.6;
  letter-spacing: -.2px;
  text-shadow: 0 1px 6px rgba(0,0,0,.85);
}

/* MODERNA — mayúsculas muy apretadas, tipo portada */
.gl-visor-txt.moderna {
  font-family: var(--fuente-ui);
  font-weight: 800;
  font-size: 22px;
  line-height: 1.1;
  letter-spacing: -1px;
  text-transform: uppercase;
  text-shadow: 0 2px 12px rgba(0,0,0,.6);
}

/* En marcos estrechos el titular no cabe: baja de tamaño con el ancho */
@media (max-width: 420px) {
  .gl-visor-txt { font-size: 18px; }
  .gl-visor-txt.neon { font-size: 26px; }
  .gl-visor-txt.moderna { font-size: 19px; }
}
.gl-visor-acc { display: flex; align-items: center; gap: 10px; }
.gl-visor-responder {
  flex: 1;
  padding: 9px 15px;
  border: 1px solid rgba(255,255,255,.55);
  border-radius: var(--radio-capsula);
  font-size: 12.5px;
  color: rgba(255,255,255,.8);
  cursor: pointer;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.gl-visor-responder:hover { border-color: #fff; color: #fff; }
.gl-visor-like {
  display: flex; align-items: center; gap: 6px;
  background: none; border: none;
  color: #fff; cursor: pointer;
  padding: 4px 2px;
  font-family: var(--fuente-ui);
}
.gl-visor-corazon {
  font-size: 21px;
  line-height: 1;
  color: rgba(255,255,255,.9);
  text-shadow: 0 1px 5px rgba(0,0,0,.6);
  transition: transform .18s cubic-bezier(.2,1.6,.3,1), color .18s ease;
}
.gl-visor-like:hover .gl-visor-corazon { transform: scale(1.12); }
.gl-visor-like.dado .gl-visor-corazon {
  color: #ff3040;
  transform: scale(1.15);
  filter: drop-shadow(0 0 9px rgba(255,48,64,.8));
}
.gl-visor-likes {
  font-size: 11.5px;
  color: rgba(255,255,255,.85);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 4px rgba(0,0,0,.6);
}

/* El recuadro de slot vacío, centrado dentro del marco */
.gl-visor-medio .media-slot { width: auto; height: auto; margin: auto; }
.gl-slot-historia { max-width: 380px; }
.gl-visor-medio img, .gl-visor-medio video { max-width: 100%; max-height: 100%; border-radius: 10px; object-fit: contain; }

/* =========================================================
   PESTAÑA 2 — PERFIL DE MATT
   ========================================================= */
.gl-perfil { overflow-y: auto; padding: 26px 30px 40px; }
.gl-pf-cab { display: flex; gap: 34px; align-items: center; margin-bottom: 30px; }
.dc-avatar.xl { width: 120px; height: 120px; }
.dc-avatar.xl .dc-avatar-ini { font-size: 42px; }
.gl-pf-der { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 16px; }
.gl-pf-fila { display: flex; align-items: center; gap: 16px; }
.gl-pf-user { font-size: 19px; font-weight: 400; }
.gl-pf-editar {
  background: #363636; border: none; color: #f5f5f5;
  font-size: 13px; font-weight: 600;
  padding: 7px 16px; border-radius: 8px; cursor: pointer;
}
.gl-pf-editar:hover { background: #4a4a4a; }
.gl-pf-stats { display: flex; gap: 34px; }
.gl-pf-stat { font-size: 13.5px; color: var(--ig-tenue); }
.gl-pf-stat b { color: #f5f5f5; font-weight: 600; }
.gl-pf-bio { font-size: 13.5px; line-height: 1.55; }
.gl-pf-nombre { font-weight: 600; }
.gl-pf-web { color: #4a9eff; margin-top: 2px; }

.gl-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  border-top: 1px solid var(--ig-borde);
  padding-top: 22px;
}
.gl-grid-celda { aspect-ratio: 1 / 1; overflow: hidden; background: #0a0a0a; }
.gl-slot-grid, .gl-slot-grid img { width: 100%; height: 100%; }
.gl-slot-grid img { object-fit: cover; }
.gl-slot-grid .media-slot {
  width: 100%; height: 100%;
  border-radius: 0; min-width: 0; min-height: 0;
  padding: 8px; justify-content: center;
}
.gl-slot-grid .media-slot-id { font-size: 9.5px; }
.gl-slot-grid .media-slot-ico { font-size: 18px; }

/* ---------------------------------------------------------
   SELECTOR DE FOTO DE MATT — compartido por las cuatro apps
   ---------------------------------------------------------
   Se despliega DENTRO de la ventana que lo pide (Wisp, Kord,
   Glim o Habitat), no como diálogo del escritorio: así el
   jugador ve al momento cómo le queda la cara en esa app.
   Neutro a propósito, para que no desentone en ninguna.
   --------------------------------------------------------- */
.sel-avatar {
  border: 1px solid var(--borde-fuerte);
  border-radius: 12px;
  background: linear-gradient(160deg, rgba(24,30,46,.97), rgba(13,16,25,.97));
  backdrop-filter: var(--blur-cristal);
  -webkit-backdrop-filter: var(--blur-cristal);
  box-shadow: var(--sombra-flotante);
  margin: 10px;
  overflow: hidden;
  flex: 0 0 auto;
  animation: aparecer .2s cubic-bezier(.2,.8,.2,1);
}
.sel-av-cab {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 11px 13px;
  border-bottom: 1px solid var(--borde);
}
.sel-av-tit {
  flex: 1;
  font-family: var(--fuente-ui);
  font-size: 13px;
  font-weight: 600;
  color: var(--texto);
}
/* Recordatorio de que el cambio no se propaga a las demás apps */
.sel-av-nota {
  font-family: var(--fuente-mono);
  font-size: 9.5px;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--acento-ambar);
  background: rgb(var(--rgb-ambar) / .10);
  border: 1px solid rgb(var(--rgb-ambar) / .28);
  padding: 3px 8px;
  border-radius: var(--radio-capsula);
  cursor: help;
}
.sel-av-x {
  background: none;
  border: none;
  color: var(--texto-tenue);
  font-size: 20px;
  line-height: 1;
  padding: 0 4px;
}
.sel-av-x:hover { color: var(--texto); }

.sel-av-rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
  gap: 9px;
  padding: 12px;
  max-height: 260px;
  overflow-y: auto;
}
.sel-av-cara {
  position: relative;
  aspect-ratio: 1 / 1;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 50%;
  overflow: hidden;
  background: var(--panel-alto);
  transition: transform .16s cubic-bezier(.2,.8,.2,1),
              border-color .16s ease, box-shadow .2s ease;
}
.sel-av-cara img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sel-av-cara:hover {
  transform: translateY(-2px) scale(1.05);
  border-color: var(--borde-glow);
  box-shadow: 0 0 16px rgb(var(--rgb-violeta) / .45);
}
/* La puesta en ESTA app */
.sel-av-cara.activa {
  border-color: var(--acento-violeta);
  box-shadow: 0 0 0 2px rgb(var(--rgb-violeta) / .35), 0 0 18px rgb(var(--rgb-violeta) / .5);
}
.sel-av-cara.activa::after {
  content: '✓';
  position: absolute;
  right: 3px;
  bottom: 3px;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  background: var(--acento-violeta);
  box-shadow: 0 0 8px rgb(var(--rgb-violeta) / .9);
}

/* Zonas que ahora se pueden pulsar para cambiar la foto */
.kord-yo { cursor: pointer; transition: background .15s ease; }
.kord-yo:hover { background: #2b2d31; }
.wisp-yo:hover, .hab-yo-chip:hover { filter: brightness(1.12); }

/* =========================================================
   PESTAÑA 3 — MENSAJES DIRECTOS
   ========================================================= */
.gl-dm { flex-direction: row; display: flex; min-height: 0; }

.gl-dm-lista {
  width: 290px; flex: 0 0 auto;
  border-right: 1px solid var(--ig-borde);
  overflow-y: auto;
  background: #000;
}
.gl-dm-cab {
  padding: 14px 16px;
  font-size: 15px; font-weight: 700;
  border-bottom: 1px solid var(--ig-borde);
}
.gl-dm-item {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  background: transparent; border: none;
  padding: 10px 14px;
  text-align: left; color: #f5f5f5; cursor: pointer;
}
.gl-dm-item:hover  { background: #121212; }
.gl-dm-item.activo { background: #1a1a1a; }
.gl-dm-centro { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.gl-dm-fila { display: flex; align-items: center; gap: 8px; }
.gl-dm-nom {
  flex: 1; font-size: 13.5px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gl-dm-hora { font-size: 11px; color: var(--ig-tenue); }
.gl-dm-prev {
  flex: 1; font-size: 12.5px; color: var(--ig-tenue);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Foto privada sin abrir */
.gl-dm-foto {
  flex: 0 0 auto;
  font-size: 10.5px; font-weight: 700;
  color: #000; background: linear-gradient(45deg, #dc2743, #cc2366);
  padding: 2px 7px; border-radius: 10px;
  color: #fff;
}

.gl-dm-chat { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.gl-chat-cab {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--ig-borde);
  flex: 0 0 auto;
}
.gl-chat-nom { font-size: 14px; font-weight: 600; }
.gl-chat-hilo { flex: 1; display: flex; flex-direction: column; min-height: 0; }

.gl-dm-vacio {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 10px;
  color: var(--ig-tenue); font-size: 13.5px;
}
.gl-dm-vacio-ico {
  font-size: 34px;
  width: 78px; height: 78px; border-radius: 50%;
  border: 2px solid var(--ig-tenue);
  display: grid; place-items: center;
}

/* Burbujas de DM (estilo Instagram) */
.estilo-glim .burbuja.suya { background: #262626; color: #f5f5f5; }
.estilo-glim .burbuja.mia  { background: #3797f0; color: #fff; }
.hilo.estilo-glim { background: #000; }
.app-glim .opciones { background: #000; border-top-color: var(--ig-borde); }
.app-glim .opcion {
  background: #1a1a1a; border-color: var(--ig-borde); color: #f5f5f5;
}
.app-glim .opcion:hover:not(.bloqueada) { background: #262626; border-color: var(--ig-azul); }

/* =========================================================
   4. HABITAT — el mundo social (tipo Habbo)
   ========================================================= */
.app-habitat {
  display: flex;
  width: 100%;
  background: #0e1119;
  color: #e8ecf5;
  --hb-panel: #151a26;
  --hb-borde: #232b3d;
  --hb-oro: #e7c15a;
  --hb-tenue: #8b95ab;
}

/* ---- Lateral: créditos + rares + amigos ---- */
.hab-lateral {
  width: 250px; flex: 0 0 auto;
  background: var(--hb-panel);
  border-right: 1px solid var(--hb-borde);
  display: flex; flex-direction: column;
  min-height: 0;
}
.hab-creditos {
  padding: 14px 16px;
  border-bottom: 1px solid var(--hb-borde);
  background: linear-gradient(135deg, #1a2133, #161d2c);
}
.hab-cred-tit { font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: var(--hb-tenue); }
.hab-cred-num { font-size: 20px; font-weight: 800; color: #7fd6ff; margin-top: 3px; font-variant-numeric: tabular-nums; }

.hab-cred-rares { font-size: 11px; color: var(--hb-oro); margin-top: 4px; }

/* Navegador de salas públicas */
.hab-salas-tit {
  padding: 12px 16px 6px;
  font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: var(--hb-tenue);
}
.hab-salas { padding: 0 8px 4px; display: flex; flex-direction: column; gap: 2px; }
.hab-sala-btn {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: transparent; border: none; color: #e8ecf5; font-family: inherit; text-align: left;
  padding: 6px 8px; border-radius: 8px; cursor: pointer;
}
.hab-sala-btn:hover { background: rgba(255,255,255,.05); }
.hab-sala-btn.aqui { background: rgba(127,214,255,.09); }
.hab-sala-btn-nom { flex: 1; font-size: 12.5px; font-weight: 600; }
.hab-sala-btn-npc {
  font-size: 10.5px; font-weight: 700; color: #241a04; background: var(--hb-oro);
  padding: 1px 6px; border-radius: 10px;
}
/* Lista de amigos */
.hab-amigos-tit {
  padding: 12px 16px 6px;
  font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: var(--hb-tenue);
}
.hab-amigos { flex: 1; overflow-y: auto; padding: 0 8px 10px; }
.hab-amigo {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  background: transparent; border: none;
  color: #e8ecf5; text-align: left;
  padding: 7px 8px; border-radius: 8px; cursor: pointer;
}
.hab-amigo:hover { background: rgba(255,255,255,.05); }
.hab-amigo.aqui  { background: rgba(127,214,255,.09); }
.hab-amigo-info { flex: 1; min-width: 0; }
.hab-amigo-nom { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hab-amigo-donde { font-size: 11px; color: var(--hb-tenue); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- Main: sala + chat ---- */
.hab-main { flex: 1; display: flex; flex-direction: column; min-width: 0; position: relative; }

/* Fondo de sala (detrás de todo el main) */
.hab-fondo {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden;
  background: linear-gradient(160deg, #1c2740, #141a2b 70%);
}
.hab-fondo.vip     { background: linear-gradient(160deg, #2a2334, #1a1424 70%); }
.hab-fondo.privada { background: linear-gradient(160deg, #2a1730, #17111f 70%); }
.hab-fondo-img { width: 100%; height: 100%; object-fit: cover; opacity: .55; }
/* Velo para que el chat se lea sobre cualquier fondo */
.hab-fondo::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8,10,16,.35) 0%, rgba(8,10,16,.72) 60%, rgba(8,10,16,.9) 100%);
}
.hab-ambiente { position: absolute; inset: 0; }
.hab-ambiente span { position: absolute; font-size: 40px; opacity: .28; filter: grayscale(.2); }

/* Cabecera de sala */
.hab-cab {
  position: relative; z-index: 1;
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px;
  background: rgba(12,15,24,.55);
  border-bottom: 1px solid rgba(255,255,255,.06);
  backdrop-filter: blur(3px);
  flex: 0 0 auto;
}
.hab-sala-nom { font-size: 15px; font-weight: 700; flex: 1; }
.hab-online { font-size: 12px; color: var(--hb-tenue); }

/* Chips de quién está en la sala */
.hab-presentes {
  position: relative; z-index: 1;
  display: flex; gap: 8px; flex-wrap: wrap;
  padding: 10px 16px;
  flex: 0 0 auto;
}
.hab-presente {
  display: flex; align-items: center; gap: 7px;
  background: rgba(20,26,40,.75); border: 1px solid var(--hb-borde);
  color: #e8ecf5; font-size: 12px;
  padding: 4px 10px 4px 4px; border-radius: 20px; cursor: pointer;
}
.hab-presente:hover { border-color: var(--hb-oro); }
.hab-yo-chip {
  display: flex; align-items: center; gap: 7px;
  background: rgba(20,26,40,.75); border: 1px solid var(--hb-borde);
  color: #e8ecf5; font-size: 12px; font-family: inherit;
  padding: 3px 10px 3px 3px; border-radius: 20px; cursor: pointer;
}
.hab-yo-chip:hover { border-color: var(--hb-oro); }

/* ---- El mundo (src/apps/habitat-mundo.js) y el chat debajo ----
   La sala se lleva el sitio grande; el chat queda como un registro
   de lo dicho más las opciones. Los bocadillos van sobre la sala. */
.hab-escena { position: relative; flex: 1 1 58%; min-height: 220px; }
.hab-mundo {
  position: absolute; inset: 0;
  overflow: hidden;
  background: radial-gradient(ellipse at 50% 35%, #1d2338 0%, #0b0e17 75%);
}
/* Al decorar, la sala se estrecha y el panel ocupa la derecha */
.hab-escena.decorando .hab-mundo, .hab-escena.tratando .hab-mundo { right: 248px; }
.hm-lienzo { position: absolute; inset: 0; display: block; touch-action: none; }
.hm-bocadillos { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.hm-bocadillo {
  position: absolute; max-width: 260px;
  padding: 5px 10px 6px;
  background: #f4f5f8; color: #1a1d26;
  border: 2px solid #1a1d26; border-radius: 9px;
  box-shadow: 0 2px 0 rgba(0,0,0,.35);
  font: 500 12px/1.35 var(--fuente-texto);
  transition: top .25s ease, opacity .4s ease;
}
.hm-bocadillo b { color: var(--quien, #333); filter: brightness(.7) saturate(1.3); }
.hm-bocadillo.mio { background: #e8f1ff; }
.hm-bocadillo.fuera { opacity: 0; }
.hm-bocadillo::after {
  content: ''; position: absolute; left: 50%; bottom: -8px; margin-left: -6px;
  border: 6px solid transparent; border-top-color: #1a1d26; border-bottom: 0;
}

/* ---- La sala de Matt: acceso, botón Decorar, panel y barra ---- */
.hab-mi-sala {
  display: flex; align-items: center; gap: 10px;
  margin: 10px 8px 0; padding: 8px 10px;
  background: rgba(231,193,90,.07); border: 1px solid #3a3320; border-radius: 10px;
  color: #e8ecf5; text-align: left; font-family: inherit; cursor: pointer;
}
.hab-mi-sala:hover { border-color: var(--hb-oro); }
.hab-mi-sala.aqui { background: rgba(231,193,90,.14); border-color: var(--hb-oro); }
.hab-mi-sala-ico { font-size: 22px; line-height: 1; }

.hab-decorar {
  background: rgba(231,193,90,.12); border: 1px solid #4a3d18; color: var(--hb-oro);
  font-weight: 700; font-size: 12px; font-family: var(--fuente-ui, inherit); padding: 6px 12px; border-radius: 20px; cursor: pointer;
}
.hab-decorar:hover, .hab-decorar.activo { background: var(--hb-oro); color: #241a04; }

.hab-deco {
  position: absolute; top: 0; right: 0; bottom: 0; width: 248px;
  display: flex; flex-direction: column; min-height: 0;
  background: var(--hb-panel); border-left: 1px solid var(--hb-borde);
}
.hab-deco-cab { display: flex; align-items: center; padding: 10px 12px 6px; }
.hab-deco-cab b { flex: 1; font-size: 13px; letter-spacing: .5px; color: var(--hb-oro); }
.hab-deco-x { background: none; border: none; color: var(--hb-tenue); font-size: 20px; line-height: 1; cursor: pointer; }
.hab-deco-x:hover { color: #fff; }
.hab-deco-tabs { display: flex; gap: 4px; padding: 0 10px 8px; border-bottom: 1px solid var(--hb-borde); }
.hab-deco-tab {
  flex: 1; background: #1c2333; border: 1px solid var(--hb-borde); color: var(--hb-tenue);
  font-weight: 600; font-size: 12px; font-family: inherit; padding: 6px 4px; border-radius: 8px; cursor: pointer;
}
.hab-deco-tab.activa { background: #26304a; color: #e8ecf5; border-color: #3a4a6a; }
.hab-deco-aviso {
  margin: 8px 10px 0; padding: 8px 10px; border-radius: 8px;
  background: rgba(95,242,160,.1); border: 1px solid #1f5a3f; color: #9ff0c4; font-size: 11.5px; line-height: 1.35;
}
.hab-deco-lista { flex: 1; overflow-y: auto; padding: 8px 10px 12px; min-height: 0; }
.hab-deco-cats { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 8px; }
.hab-deco-cat {
  background: transparent; border: 1px solid var(--hb-borde); color: var(--hb-tenue);
  font-size: 11px; font-family: inherit; padding: 3px 9px; border-radius: 20px; cursor: pointer;
}
.hab-deco-cat.activa { border-color: var(--hb-oro); color: var(--hb-oro); }
.hab-deco-rejilla { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
.hab-furni {
  display: flex; flex-direction: column; gap: 3px; min-width: 0;
  background: #1a2030; border: 1px solid var(--hb-borde); border-radius: 9px; padding: 5px;
}
.hab-furni.pulsable { cursor: pointer; }
.hab-furni.pulsable:hover { border-color: #5ff2a0; }
.hab-furni-vista {
  height: 64px; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(ellipse at 50% 60%, #252d42 0%, #141927 80%); border-radius: 6px; overflow: hidden;
}
.hab-furni-muestra { width: 56px; height: 44px; border-radius: 5px; border: 1px solid rgba(255,255,255,.15); }
.hab-furni-nom { font-size: 11px; font-weight: 600; line-height: 1.2; min-height: 2.4em; }
.hab-furni-pie { display: flex; flex-direction: column; align-items: stretch; gap: 3px; }
.hab-furni-vista canvas { max-width: 100%; }
.hab-furni-precio { font-size: 10.5px; color: #7fd6ff; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hab-furni-btn {
  background: linear-gradient(135deg, #3a6df0, #2b52c9); color: #fff; border: none;
  font-weight: 700; font-size: 10.5px; font-family: inherit; padding: 4px 7px; border-radius: 6px; cursor: pointer;
}
.hab-furni-btn:disabled { background: #222a3b; color: var(--hb-tenue); cursor: default; }
.hab-deco-vacio { font-size: 12px; color: var(--hb-tenue); line-height: 1.4; padding: 6px 2px 10px; }
.hab-deco-sub { margin: 12px 0 6px; font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: var(--hb-tenue); }
.hab-deco-pinturas { display: flex; flex-wrap: wrap; gap: 6px; }
.hab-pintura { width: 30px; height: 30px; border-radius: 7px; border: 2px solid var(--hb-borde); cursor: pointer; }
.hab-pintura:hover { border-color: #e8ecf5; }
.hab-pintura.puesta { border-color: var(--hb-oro); box-shadow: 0 0 0 2px rgba(231,193,90,.3); }

/* ---- Rares: etiqueta de rareza y tarjetas con marco ---- */
.hab-rareza {
  align-self: flex-start;
  font-size: 9.5px; font-weight: 800; letter-spacing: .4px; text-transform: uppercase;
  color: var(--rareza); border: 1px solid var(--rareza); border-radius: 6px; padding: 0 5px;
  background: color-mix(in srgb, var(--rareza) 14%, transparent);
}
.hab-furni.rare {
  border-color: var(--rareza);
  box-shadow: 0 0 10px color-mix(in srgb, var(--rareza) 35%, transparent) inset;
}

/* ---- El puesto de un comerciante (mismo sitio que Decorar) ---- */
.hab-trato {
  position: absolute; top: 0; right: 0; bottom: 0; width: 248px;
  display: flex; flex-direction: column; min-height: 0;
  background: var(--hb-panel); border-left: 1px solid #4a3d18;
}
.hab-trato-sub { padding: 0 12px 8px; font-size: 10.5px; color: var(--hb-tenue); line-height: 1.35; border-bottom: 1px solid var(--hb-borde); }
.hab-trato-fila {
  display: grid; grid-template-columns: 58px minmax(0, 1fr); gap: 4px 8px;
  background: #1a2030; border: 1px solid var(--hb-borde); border-radius: 9px; padding: 6px; margin-bottom: 6px;
}
.hab-trato-vista { height: 46px; }
.hab-trato-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.hab-trato-info .hab-furni-nom { min-height: 0; }
.hab-trato-det { font-size: 10.5px; color: var(--hb-tenue); }
.hab-trato-pista { font-size: 10.5px; color: #8fb8ff; line-height: 1.3; }
.hab-trato-pista.gana { color: #7fe0a8; }
.hab-trato-accion { grid-column: 1 / -1; display: flex; align-items: center; gap: 6px; }
.hab-trato-accion .hab-furni-precio { flex: 1; font-size: 12px; font-weight: 700; }
.hab-furni-btn.vender { background: linear-gradient(135deg, #ffd257, #e7a92e); color: #241a04; }
.hab-furni-btn.vender:disabled { background: #222a3b; color: var(--hb-tenue); }
.hab-deco-barra {
  position: absolute; left: 10px; bottom: 10px; z-index: 2;
  display: flex; align-items: center; gap: 6px; max-width: calc(100% - 268px);
  padding: 6px 8px 6px 12px; border-radius: 12px;
  background: rgba(12,15,24,.92); border: 1px solid #4a3d18;
  box-shadow: 0 4px 16px rgba(0,0,0,.4);
}
.hab-deco-barra b { font-size: 12px; color: var(--hb-oro); margin-right: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hab-deco-barra button {
  background: #1c2333; border: 1px solid var(--hb-borde); color: #e8ecf5;
  font-weight: 600; font-size: 11.5px; font-family: inherit; padding: 5px 9px; border-radius: 8px; cursor: pointer; white-space: nowrap;
}
.hab-deco-barra button:hover { border-color: var(--hb-oro); }

.hab-conv {
  position: relative; z-index: 1; flex: 1 1 42%; display: flex; flex-direction: column; min-height: 0;
  border-top: 1px solid var(--hb-borde); background: #0e1119;
}
.hilo.estilo-habitat { background: transparent; }
.app-habitat .opciones { background: rgba(12,15,24,.92); border-top-color: rgba(255,255,255,.08); }
.app-habitat .opcion { background: rgba(30,37,55,.92); border-color: var(--hb-borde); color: #e8ecf5; }
.app-habitat .opcion:hover:not(.bloqueada) { background: rgba(40,50,74,.95); border-color: var(--hb-oro); }
.app-habitat .dc-sistema { color: #aab4c8; }

/* =========================================================
   5. VAPOR — el Steam falso (CLIENTE DE JUEGOS)
   ========================================================= */
.app-vapor {
  display: flex; flex-direction: column;
  width: 100%;
  background: #0d1420;
  color: #dbe4ee;
  --vp-panel: #141d2b;
  --vp-panel2: #1b2636;
  --vp-borde: #26313f;
  --vp-azul: #4a9eff;
  --vp-oro: #f0c674;
  --vp-tenue: #8a97a8;
  --vp-win: #4ac47a;
  --vp-loss: #e06666;
}

/* Nav superior */
.vp-nav {
  display: flex; align-items: center; gap: 16px;
  padding: 10px 16px;
  background: #0a0f18;
  border-bottom: 1px solid var(--vp-borde);
  flex: 0 0 auto;
}
.vp-logo { font-size: 18px; font-weight: 800; letter-spacing: 3px; color: var(--vp-azul); }
.vp-tabs { display: flex; gap: 4px; }
.vp-tab {
  background: transparent; border: none; color: var(--vp-tenue);
  font-size: 13px; padding: 8px 14px; border-radius: 8px; cursor: pointer;
}
.vp-tab:hover { background: #17202e; color: #dbe4ee; }
.vp-tab.activo { color: #fff; background: #1d2a3d; font-weight: 700; }
.vp-cartera { margin-left: auto; font-size: 13px; font-weight: 600; color: #7fd6a0; font-variant-numeric: tabular-nums; }

.vp-cuerpo { flex: 1; min-height: 0; overflow-y: auto; padding: 18px; }
.vp-nota { font-size: 11.5px; color: var(--vp-tenue); font-style: italic; line-height: 1.5; padding: 6px 2px; }
.vp-hist-tit { font-size: 11px; font-weight: 700; letter-spacing: 1px; color: var(--vp-tenue); margin: 16px 2px 10px; }
.vp-cuerpo > .vp-hist-tit:first-child { margin-top: 4px; }

/* ---- JUGAR ---- */
.vp-banner {
  position: relative; height: 160px; border-radius: 12px; overflow: hidden;
  background: linear-gradient(135deg, #1c3358, #142033);
}
.vp-banner img { width: 100%; height: 100%; object-fit: cover; opacity: .8; }
.vp-banner.sin-img::after {
  content: 'RIFT LEGENDS'; position: absolute; inset: 0;
  display: grid; place-items: center; font-size: 28px; font-weight: 800;
  letter-spacing: 5px; color: rgba(255,255,255,.08);
}
.vp-banner-tit { position: absolute; left: 18px; bottom: 14px; display: flex; flex-direction: column; text-shadow: 0 2px 8px rgba(0,0,0,.8); }
.vp-banner-tit span { font-size: 24px; font-weight: 800; letter-spacing: 1px; }
.vp-banner-tit small { font-size: 12px; color: #b9c6d6; }

.vp-servidor { display: flex; align-items: center; gap: 8px; padding: 12px 2px 4px; font-size: 12.5px; color: var(--vp-tenue); }
.vp-servidor b { color: var(--vp-win); }
.vp-srv-punto { width: 9px; height: 9px; border-radius: 50%; background: var(--vp-win); box-shadow: 0 0 8px var(--vp-win); }

.vp-rango-card {
  display: flex; align-items: center; gap: 16px;
  background: var(--vp-panel); border: 1px solid var(--vp-borde);
  border-radius: 12px; padding: 16px; margin: 8px 0;
}
.vp-rango-badge {
  width: 54px; height: 54px; border-radius: 12px; flex: 0 0 auto;
  display: grid; place-items: center; font-size: 26px; color: #1a1206;
  background: linear-gradient(135deg, #ffe08a, #f0c674 45%, #c9962e);
  box-shadow: 0 0 18px rgba(240,198,116,.55);
  animation: vpBrillo 2.4s ease-in-out infinite alternate;
}
@keyframes vpBrillo { from { box-shadow: 0 0 12px rgba(240,198,116,.4); } to { box-shadow: 0 0 28px rgba(240,198,116,.8); } }
.vp-rango-mid { flex: 1; min-width: 0; }
.vp-rango-fila { display: flex; align-items: baseline; gap: 10px; }
.vp-rango-fila b { font-size: 18px; color: var(--vp-oro); letter-spacing: .5px; }
.vp-lp { font-size: 13px; color: #cdd8e4; font-variant-numeric: tabular-nums; }
.vp-lp-barra { height: 9px; border-radius: 6px; background: #0d1420; border: 1px solid var(--vp-borde); overflow: hidden; margin: 8px 0 6px; }
.vp-lp-fill { height: 100%; border-radius: 6px; background: linear-gradient(90deg, #f0c674, #ffe08a); transition: width 1s cubic-bezier(.2,.8,.2,1); }
.vp-rango-sub { font-size: 11.5px; color: var(--vp-tenue); }

.vp-partida-estado { text-align: center; font-size: 13px; color: #cdd8e4; padding: 6px; font-variant-numeric: tabular-nums; }

.vp-play {
  width: 100%; border: none; border-radius: 12px; cursor: pointer;
  padding: 20px; font-size: 20px; font-weight: 800; letter-spacing: 1px;
  color: #fff; background: linear-gradient(135deg, #3a8bff, #2358c9);
  box-shadow: 0 8px 24px rgba(58,139,255,.3);
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  transition: filter .15s, transform .1s;
}
.vp-play small { font-size: 11px; font-weight: 600; letter-spacing: 2px; opacity: .85; }
.vp-play:hover:not(:disabled) { filter: brightness(1.08); }
.vp-play:active:not(:disabled) { transform: scale(.99); }
.vp-play:disabled { background: #1b2636; color: var(--vp-tenue); box-shadow: none; cursor: not-allowed; }

/* ---- ESTADÍSTICAS ---- */
.vp-lp-graf { background: var(--vp-panel); border: 1px solid var(--vp-borde); border-radius: 12px; padding: 14px; }
.vp-svg-cont { }
.vp-svg { width: 100%; height: 90px; display: block; }
.vp-svg-area { fill: rgba(240,198,116,.12); stroke: none; }
.vp-svg-linea { fill: none; stroke: var(--vp-oro); stroke-width: 1.4; vector-effect: non-scaling-stroke; }
.vp-svg-pie { display: flex; justify-content: space-between; font-size: 10.5px; color: var(--vp-tenue); margin-top: 6px; }

.vp-hist-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px; }
.vp-mcard { background: var(--vp-panel); border: 1px solid var(--vp-borde); border-left: 3px solid; border-radius: 0 10px 10px 0; padding: 12px; }
.vp-mcard.win  { border-left-color: var(--vp-win); }
.vp-mcard.loss { border-left-color: var(--vp-loss); }
.vp-mcard-cab { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.vp-mcard-res { font-size: 12px; font-weight: 800; }
.vp-mcard.win .vp-mcard-res  { color: var(--vp-win); }
.vp-mcard.loss .vp-mcard-res { color: var(--vp-loss); }
.vp-mvp { font-size: 10px; font-weight: 800; color: #1a1206; background: var(--vp-oro); padding: 1px 6px; border-radius: 4px; }
.vp-mcard-lp { margin-left: auto; font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; }
.vp-mcard-lp.pos { color: var(--vp-win); }
.vp-mcard-lp.neg { color: var(--vp-loss); }
.vp-mcard-camp { font-size: 14px; font-weight: 700; margin-bottom: 8px; }
.vp-mcard-stats { display: flex; gap: 10px; }
.vp-mcard-stats span { display: flex; flex-direction: column; }
.vp-mcard-stats b { font-size: 13px; font-variant-numeric: tabular-nums; }
.vp-mcard-stats small { font-size: 9.5px; color: var(--vp-tenue); }

/* ---- GAME HUB ---- */
.vp-stream { background: var(--vp-panel); border: 1px solid var(--vp-borde); border-radius: 12px; overflow: hidden; }
.vp-stream-thumb { position: relative; aspect-ratio: 16/9; background: #0a0f18; cursor: zoom-in; }
.vp-stream-thumb img, .vp-stream-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.vp-stream-thumb .media-slot { width: 100%; height: 100%; min-width: 0; min-height: 0; border-radius: 0; justify-content: center; }
.vp-live { position: absolute; top: 10px; left: 10px; font-size: 11px; font-weight: 800; color: #fff; background: #e0245e; padding: 3px 8px; border-radius: 5px; letter-spacing: .5px; }
.vp-espectadores { position: absolute; bottom: 10px; left: 10px; font-size: 11px; color: #fff; background: rgba(0,0,0,.6); padding: 3px 8px; border-radius: 5px; }
.vp-stream-info { display: flex; align-items: center; gap: 10px; padding: 12px 14px; }
.vp-stream-tit { font-size: 13.5px; font-weight: 700; }
.vp-stream-sub { font-size: 11.5px; color: var(--vp-tenue); }

.vp-noticia { display: flex; gap: 12px; background: var(--vp-panel); border: 1px solid var(--vp-borde); border-radius: 10px; padding: 12px 14px; margin-bottom: 8px; }
.vp-noticia-tag { flex: 0 0 auto; height: fit-content; font-size: 10px; font-weight: 800; letter-spacing: .5px; padding: 3px 8px; border-radius: 5px; color: #0d1420; }
.tag-parche  { background: var(--vp-azul); }
.tag-evento  { background: var(--vp-oro); }
.tag-esports { background: #b98cff; }
.vp-noticia-tit { font-size: 13px; font-weight: 700; }
.vp-noticia-txt { font-size: 12px; color: var(--vp-tenue); line-height: 1.5; margin-top: 3px; }

.vp-biblioteca { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; }
.vp-lib-juego { background: var(--vp-panel); border: 1px solid var(--vp-borde); border-radius: 10px; padding: 12px; }
.vp-lib-juego.principal { border-color: var(--vp-azul); }
.vp-lib-nom { font-size: 13.5px; font-weight: 700; }
.vp-lib-gen { font-size: 11px; color: var(--vp-tenue); margin: 2px 0 6px; }
.vp-lib-horas { font-size: 11px; color: #cdd8e4; }

/* ---- TIENDA ---- */
.vp-tienda-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; margin-top: 6px; }
.vp-titem { background: var(--vp-panel); border: 1px solid var(--vp-borde); border-radius: 12px; overflow: hidden; display: flex; flex-direction: column; }
.vp-titem.comprado { opacity: .75; }
.vp-titem-img { aspect-ratio: 16/9; background: #0a0f18; overflow: hidden; }
.vp-titem-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vp-titem-img.es-pase { background: linear-gradient(135deg, #2a2140, #1a1530); }
.vp-titem-img .media-slot { width: 100%; height: 100%; min-width: 0; min-height: 0; border-radius: 0; justify-content: center; padding: 8px; }
.vp-titem-img .media-slot-id { font-size: 9px; }
.vp-titem-cuerpo { padding: 12px; display: flex; flex-direction: column; gap: 5px; flex: 1; }
.vp-titem-nom { font-size: 13.5px; font-weight: 700; }
.vp-titem-desc { font-size: 11.5px; color: var(--vp-tenue); line-height: 1.45; flex: 1; }
.vp-titem-fila { display: flex; align-items: center; justify-content: space-between; margin-top: 4px; }
.vp-titem-precio { font-size: 15px; font-weight: 700; color: var(--vp-oro); }
.vp-titem-btn { background: linear-gradient(135deg, #3a8bff, #2358c9); color: #fff; border: none; font-size: 12px; font-weight: 700; padding: 8px 14px; border-radius: 8px; cursor: pointer; }
.vp-titem-btn:hover:not(:disabled) { filter: brightness(1.08); }
.vp-titem-btn:disabled { background: #1b2636; color: var(--vp-win); cursor: default; }

.dc-estado.partida { background: var(--vp-azul); }

/* =========================================================
   6. REPRODUCTOR
   ========================================================= */
.app-player { display: flex; flex-direction: column; width: 100%; min-height: 0; }

/* --- Pestanas: Biblioteca / Mezclador --- */
.pl-tabs {
  display: flex;
  gap: 4px;
  padding: 8px 10px 0;
  border-bottom: 1px solid var(--borde);
  flex: 0 0 auto;
}
.pl-tab {
  background: transparent;
  border: 1px solid transparent;
  border-bottom: none;
  color: var(--texto-tenue);
  font-family: var(--fuente-ui);
  font-size: 12px;
  padding: 7px 14px;
  border-radius: var(--radio) var(--radio) 0 0;
  cursor: pointer;
  position: relative;
  top: 1px;
}
.pl-tab:hover { color: var(--texto); }
.pl-tab.activa {
  color: var(--texto);
  background: var(--panel-alto);
  border-color: var(--borde);
  font-weight: 600;
}
/* La linea que "abre" la pestana activa hacia su contenido */
.pl-tab.activa::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: var(--panel-alto);
}

.pl-vista { display: flex; flex: 1; min-height: 0; width: 100%; }
.pl-vista[data-vista="mezclador"] { display: block; overflow-y: auto; }

.pl-biblioteca {
  width: 250px;
  flex: 0 0 auto;
  border-right: 1px solid var(--borde);
  overflow-y: auto;
  padding: 12px;
}
.pl-bib-cab {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 10px;
}
.pl-biblioteca h3 {
  margin: 0;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--texto-tenue);
}
.pl-contador {
  font-family: var(--fuente-mono);
  font-size: 10.5px;
  color: var(--texto-tenue);
}

/* Agrupadas por chica: sin esto son 35 notas en una lista plana */
.pl-grupo { margin-bottom: 14px; }
.pl-grupo-cab {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 0 4px 5px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .3px;
  color: var(--acento-suave);
  border-bottom: 1px solid var(--borde);
  margin-bottom: 5px;
}
.pl-grupo-n {
  font-family: var(--fuente-mono);
  font-size: 10px;
  color: var(--texto-tenue);
  font-weight: 400;
}

.pl-item {
  padding: 8px 10px;
  border-radius: var(--radio);
  cursor: pointer;
  margin-bottom: 3px;
  border: 1px solid transparent;
}
.pl-item:hover { background: var(--panel-alto); border-color: var(--borde); }
.pl-item.bloqueada { opacity: .32; cursor: default; }
.pl-item.bloqueada:hover { background: transparent; border-color: transparent; }
.pl-item.sonando {
  background: rgb(var(--rgb-carmesi) / .12);
  border-color: rgb(var(--rgb-carmesi) / .45);
}

.pl-item-tit { font-size: 12.5px; margin-bottom: 2px; }
.pl-item-sub { font-size: 10.5px; color: var(--texto-tenue); font-family: var(--fuente-mono); }

.pl-vacio {
  color: var(--texto-tenue);
  font-size: 12px;
  line-height: 1.6;
  font-style: italic;
  padding: 8px 0;
}

.pl-panel { flex: 1; padding: 16px; overflow-y: auto; min-width: 0; }
.pl-mezcla { padding: 16px 18px 22px; max-width: 720px; }
.pl-mezcla-ayuda {
  margin: 0 0 16px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--texto-tenue);
  opacity: .75;
}

.pl-ahora  { margin-bottom: 14px; }
.pl-titulo { font-size: 17px; font-weight: 600; }
.pl-sub    { font-size: 12px; color: var(--texto-tenue); margin-top: 2px; }

.pl-controles { margin-bottom: 22px; }
.pl-stop {
  background: var(--panel-alto);
  border: 1px solid var(--borde);
  color: var(--texto);
  padding: 7px 16px;
  border-radius: var(--radio);
  font-size: 12px;
}
.pl-stop:hover:not(:disabled) { background: var(--acento); border-color: var(--acento); color: #fff; }
.pl-stop:disabled { opacity: .35; cursor: default; }

/* ---------------- MEZCLADOR ----------------
   Sliders de verdad, no barras de lectura. El nivel se guarda en
   localStorage: es preferencia del equipo, no progreso de partida. */
.pl-mezcla-cab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.pl-mezcla h4 {
  margin: 0;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--texto-tenue);
}
.pl-reset {
  background: transparent;
  border: 1px solid var(--borde);
  color: var(--texto-tenue);
  font-size: 10.5px;
  padding: 4px 9px;
  border-radius: var(--radio-capsula);
  cursor: pointer;
}
.pl-reset:hover { color: var(--texto); border-color: var(--borde-fuerte); }

.bus-fila {
  display: grid;
  /* nombre | probar | silenciar | slider | % */
  grid-template-columns: 132px 30px 30px 1fr 42px;
  align-items: center;
  gap: 6px 10px;
  padding: 9px 0;
  border-bottom: 1px solid rgba(255,255,255,.04);
}
/* Un canal callado se ve callado de un vistazo, sin leer nada:
   se apaga entero y el mando pierde el color. */
.bus-fila.silenciado .bus-nom,
.bus-fila.silenciado .bus-val,
.bus-fila.silenciado .bus-desc { opacity: .35; }
.bus-fila.silenciado .bus-slider { accent-color: var(--texto-tenue); opacity: .45; }
.bus-fila.silenciado .bus-mute { color: var(--acento-carmesi); }

.bus-icono { margin-right: 7px; font-size: 13px; }
.bus-nom { display: flex; align-items: center; }

/* Los dos botoncitos de la fila. Mismo tamano y misma caja para que
   se lean como un par de controles y no como decoracion. */
.bus-test, .bus-mute {
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  font-size: 12px;
  line-height: 1;
  background: transparent;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  color: var(--texto-tenue);
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.bus-test:hover:not(:disabled), .bus-mute:hover {
  color: var(--texto);
  border-color: var(--borde-fuerte);
  background: rgba(255,255,255,.04);
}
.bus-test:active:not(:disabled) { transform: scale(.92); }
.bus-test:disabled { opacity: .25; cursor: default; }

/* Las cuatro pruebas del canal de interfaz, colgando de su fila */
.bus-pruebas {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  padding: 2px 0 12px 132px;
  margin-top: -6px;
  border-bottom: 1px solid rgba(255,255,255,.04);
}
.bus-pruebas-tit {
  font-size: 10.5px;
  color: var(--texto-tenue);
  opacity: .6;
  margin-right: 2px;
}
.bus-chip {
  background: transparent;
  border: 1px solid var(--borde);
  color: var(--texto-tenue);
  font-family: var(--fuente-ui);
  font-size: 10.5px;
  padding: 3px 10px;
  border-radius: var(--radio-capsula);
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.bus-chip:hover { color: var(--texto); border-color: var(--acento-violeta); }
.bus-chip:active { transform: scale(.94); }
/* El general manda sobre el resto y se nota */
.bus-fila.maestro {
  border-bottom: 1px solid var(--borde);
  padding-bottom: 11px;
  margin-bottom: 5px;
}
.bus-fila.maestro .bus-nom { color: var(--texto); font-weight: 600; }

.bus-nom { font-size: 12px; color: var(--texto-tenue); }
.bus-nom-txt { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.bus-slider {
  width: 100%;
  accent-color: var(--acento);
  cursor: pointer;
}

.bus-val {
  font-size: 10.5px;
  color: var(--texto-tenue);
  text-align: right;
  font-family: var(--fuente-mono);
  font-variant-numeric: tabular-nums;
}

/* La explicación va debajo, ocupando las tres columnas: cada mando
   dice qué toca sin tener que pasar el ratón por encima. */
.bus-desc {
  grid-column: 1 / -1;
  font-size: 10.5px;
  color: var(--texto-tenue);
  opacity: .6;
  line-height: 1.4;
  margin-top: -2px;
}

@media (max-width: 720px) {
  .pl-vista[data-vista="biblioteca"] { flex-direction: column; }
  .pl-biblioteca { width: auto; max-height: 40%; border-right: none; border-bottom: 1px solid var(--borde); }
  /* En estrecho el nombre se lleva su propia linea: apretar cinco
     columnas deja el slider en un dedo de ancho y no se puede ajustar. */
  .bus-fila { grid-template-columns: 1fr 30px 30px; }
  .bus-nom  { grid-column: 1 / -1; }
  .bus-slider { grid-column: 1 / 2; }
  .bus-pruebas { padding-left: 0; }
}

/* =========================================================
   6b. GALERÍA DE ESCENAS (extra de mecenas)
   ========================================================= */
.app-galeria {
  flex-direction: column;
  width: 100%;
  overflow-y: auto;
  padding: 0 0 18px;
}
.ga-cab {
  display: flex; align-items: baseline; gap: 12px;
  padding: 14px 18px 10px;
  position: sticky; top: 0; z-index: 2;
  background: var(--panel-alto-solido, #161b26);
  border-bottom: 1px solid var(--borde);
}
.ga-tit { font-family: var(--fuente-ui); font-size: 15px; font-weight: 600; }
.ga-cuenta {
  margin-left: auto;
  font-family: var(--fuente-mono); font-size: 11.5px;
  color: var(--acento-ambar);
}

.ga-filtros { display: flex; flex-wrap: wrap; gap: 6px; padding: 11px 18px 4px; }
.ga-chip {
  background: transparent; border: 1px solid var(--borde);
  color: var(--texto-tenue);
  font-family: var(--fuente-ui); font-size: 11.5px;
  padding: 4px 11px; border-radius: var(--radio-capsula); cursor: pointer;
}
.ga-chip:hover { color: var(--texto); border-color: var(--borde-fuerte); }
.ga-chip.activo {
  color: #fff; border-color: var(--acento-ambar);
  background: rgb(var(--rgb-ambar) / .14);
}

.ga-rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(126px, 1fr));
  grid-auto-rows: max-content;      /* mismo motivo que en el Vault */
  gap: 11px;
  padding: 13px 18px 6px;
}
.ga-ficha {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 13px 9px 11px;
  background: var(--panel);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  cursor: pointer;
  transition: border-color .15s ease, transform .15s ease, background .15s ease;
}
.ga-ficha:hover:not(.cerrada) {
  border-color: var(--acento-ambar);
  background: var(--panel-alto);
  transform: translateY(-2px);
}
/* Lo no vivido se ve, pero no se lee: que sepas que hay algo y en qué
   noche, sin que el título te destripe la escena. */
.ga-ficha.cerrada {
  cursor: default;
  opacity: .4;
  border-style: dashed;
  border-color: rgba(255,255,255,.16);
}
.ga-cara {
  width: 56px; height: 56px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(0,0,0,.3);
  font-size: 22px; color: var(--texto-tenue);
}
.ga-nom { font-family: var(--fuente-ui); font-size: 12.5px; font-weight: 600; }
.ga-sub { font-size: 10.5px; color: var(--texto-tenue); font-family: var(--fuente-mono); }
.ga-vacio, .ga-pie {
  grid-column: 1 / -1;
  color: var(--texto-tenue); font-size: 12px; line-height: 1.6;
  padding: 14px 18px;
}

/* --- Reproduciendo una escena --- */
.ga-barra {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--borde);
  flex: 0 0 auto;
}
.ga-volver {
  background: var(--panel-alto); border: 1px solid var(--borde);
  color: var(--texto); font-family: var(--fuente-ui); font-size: 11.5px;
  padding: 5px 11px; border-radius: var(--radio); cursor: pointer;
}
.ga-volver:hover { border-color: var(--acento-ambar); }
.ga-barra-nom { font-family: var(--fuente-ui); font-size: 13px; font-weight: 600; }
/* El sello de REPETICIÓN no es decorativo: es lo que le dice al
   jugador que lo que elija aquí no cuenta para su partida. */
.ga-marca {
  margin-left: auto;
  font-family: var(--fuente-mono); font-size: 9.5px; font-weight: 600;
  letter-spacing: 1.4px;
  color: var(--acento-ambar);
  border: 1px solid rgb(var(--rgb-ambar) / .45);
  background: rgb(var(--rgb-ambar) / .1);
  padding: 3px 8px; border-radius: var(--radio-capsula);
}
.ga-escena { flex: 1; min-height: 0; display: flex; }
.app-galeria .ga-escena { overflow: hidden; }

/* =========================================================
   7. REPRODUCTOR DE ESCENA (pantalla completa)
   ========================================================= */
.escena-overlay {
  position: absolute;
  inset: 0;
  background: #05070a;
  z-index: 8000;
  display: flex;
  flex-direction: column;
  animation: escenaEntra .5s ease-out;
}
.escena-overlay.saliendo { animation: escenaSale .4s ease-in forwards; }

@keyframes escenaEntra { from { opacity: 0; } to { opacity: 1; } }
@keyframes escenaSale  { to   { opacity: 0; } }

.escena-marco {
  flex: 1;
  position: relative;
  overflow: hidden;
  min-height: 0;
}

.escena-videos { position: absolute; inset: 0; }

.escena-video {
  position: absolute;
  inset: 0;
  margin: auto;
  max-width: 100%;
  max-height: 100%;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  /* Fundido cruzado lento entre fases: la escena sube de
     intensidad sin cortes. Un corte seco la rompe. */
  transition: opacity .9s ease-in-out;
  pointer-events: none;
}
.escena-video.visible { opacity: 1; }

/* Aviso cuando faltan los archivos: mejor que un rectángulo negro */
.escena-vacia {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 12px;
  color: var(--texto-tenue);
  text-align: center;
  padding: 20px;
}
.escena-vacia-ico { font-size: 40px; opacity: .5; }
.escena-vacia p {
  font-size: 12px;
  line-height: 1.7;
  white-space: pre-line;
  font-family: ui-monospace, Consolas, monospace;
  margin: 0;
}

.escena-pie {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 20px;
  background: linear-gradient(180deg, rgba(0,0,0,0) 0%, #05070a 60%);
}

.escena-info { flex: 0 0 auto; min-width: 150px; }

.escena-titulo {
  font-size: 13px;
  color: var(--texto);
  letter-spacing: .5px;
}
.escena-fase {
  font-size: 10px;
  color: var(--texto-tenue);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-top: 2px;
}

/* --- Control de intensidad --- */
.escena-intensidad {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
}

.escena-marcas { display: flex; gap: 6px; }

.escena-marca {
  width: 34px;
  height: 4px;
  border-radius: 2px;
  background: rgba(255,255,255,.15);
  transition: background .5s ease;
}
.escena-marca.activa {
  background: var(--acento-suave);
  box-shadow: 0 0 8px var(--acento);
}

.escena-mas {
  background: var(--acento);
  color: #fff;
  border: none;
  padding: 9px 22px;
  border-radius: var(--radio);
  font-size: 13px;
  letter-spacing: .5px;
  transition: background .2s, transform .1s;
}
.escena-mas:hover:not(:disabled) { background: var(--acento-suave); }
.escena-mas:active:not(:disabled) { transform: scale(.96); }
.escena-mas:disabled {
  background: transparent;
  color: var(--texto-tenue);
  border: 1px solid var(--borde);
  cursor: default;
}

.escena-cerrar {
  flex: 0 0 auto;
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 1px solid var(--borde);
  background: rgba(255,255,255,.05);
  color: var(--texto-tenue);
  font-size: 18px;
  line-height: 1;
}
.escena-cerrar:hover { background: var(--acento); color: #fff; border-color: var(--acento); }

/* Cuando el audio termina, el botón de cerrar llama la atención */
.escena-overlay.terminada .escena-cerrar {
  border-color: var(--acento);
  color: var(--acento-suave);
  animation: latido 2s ease-in-out infinite;
}
@keyframes latido {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.12); }
}

/* =========================================================
   8. PANTALLA DE FINAL
   ========================================================= */
.app-final {
  flex-direction: column;
  padding: 26px 30px;
  overflow-y: auto;
  display: flex;
}
.app-final h2 {
  margin: 0 0 14px;
  font-size: 24px;
  color: var(--acento-suave);
  letter-spacing: .5px;
}
.final-texto {
  font-size: 14px;
  line-height: 1.75;
  margin: 0 0 26px;
  user-select: text;
}

.final-datos { border-top: 1px solid var(--borde); padding-top: 16px; }
.final-fila {
  display: grid;
  grid-template-columns: 90px 1fr 90px;
  align-items: center;
  gap: 10px;
  margin-bottom: 7px;
}
.final-nom { font-size: 12px; }
.final-barra {
  height: 8px;
  background: #0d1015;
  border: 1px solid var(--borde);
  border-radius: 4px;
  overflow: hidden;
}
.final-relleno {
  height: 100%;
  background: linear-gradient(90deg, var(--acento), var(--acento-suave));
}
.final-niv {
  font-size: 10px;
  color: var(--texto-tenue);
  text-align: right;
  text-transform: uppercase;
  letter-spacing: .5px;
}

.final-pie {
  margin-top: 20px;
  font-size: 11px;
  color: var(--texto-tenue);
  font-style: italic;
}

/* =========================================================
   8. WALLPAPERS — la app de fondos del escritorio
   ========================================================= */
.app-wallpapers {
  flex-direction: column;
  width: 100%;
  padding: 14px;
  gap: 12px;
  overflow-y: auto;
}
.wp-cabecera { font-size: 13px; color: var(--texto-tenue); flex: 0 0 auto; }

.wp-galeria {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 12px;
}

.wp-card {
  background: var(--panel-alto);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-align: left;
  transition: border-color .15s, box-shadow .15s;
}
.wp-card:hover { border-color: var(--acento); }
.wp-card.activo {
  border-color: var(--acento);
  box-shadow: 0 0 0 1px var(--acento) inset;
}

.wp-thumb {
  aspect-ratio: 16 / 9;
  border-radius: 8px;
  overflow: hidden;
  background: #0b0d12;
  display: flex;
  align-items: center;
  justify-content: center;
}
.wp-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* El recuadro de slot vacío se adapta al hueco de la miniatura */
.wp-thumb .media-slot {
  border: none;
  background: transparent;
  min-width: 0;
  padding: 8px;
}
.wp-thumb .media-slot-nota { display: none; }   /* en miniatura sobra la nota larga */

.wp-nom { font-size: 12px; font-weight: 600; }

.wp-badge { font-size: 10px; color: #6cbf73; display: none; }
.wp-card.activo .wp-badge { display: block; }

/* =========================================================
   TUTORIAL — guía del Día 1
   ---------------------------------------------------------
   El tutorial es la VOZ DEL SISTEMA, no la de ninguna app: por
   eso habla siempre en violeta (--acento-violeta), el mismo
   color del foco de ventana. Si hablara en carmesí se
   confundiría con Velvet; en verde, con Wisp.

   Todas las clases tut-* las pone y las quita src/core/tutorial.js.
   Aquí solo se define cómo se ven: no hace falta tocar el JS.
   ========================================================= */

/* --- Foco tipo "spotlight" ---
   Lo que no toca no se apaga a lo bruto: se desenfoca y pierde
   color, como el fondo de una foto con poca profundidad de campo.
   Se lee al instante dónde tienes que mirar y no parece un bug. */
#icons.tut-guiando .icono {
  opacity: .3;
  filter: blur(1.5px) saturate(.35);
  transform: scale(.96);
  transition: opacity .35s ease, filter .35s ease, transform .35s ease;
}
#icons.tut-guiando .icono:hover { opacity: .5; }

/* El icono objetivo del paso: nítido, elevado y con halo violeta */
#icons.tut-guiando .icono.tut-destacado {
  opacity: 1;
  filter: none;
  transform: scale(1);
}
/* El objetivo sigue reaccionando al ratón como cualquier icono: si
   no, el único que puedes pulsar es el único que parece muerto. */
#icons.tut-guiando .icono.tut-destacado:hover {
  transform: translateY(-2px);
  background: rgb(var(--rgb-violeta) / .19);
}
.icono.tut-destacado {
  position: relative;
  z-index: 2;
  border-color: rgb(var(--rgb-violeta) / .55);
  background: rgb(var(--rgb-violeta) / .10);
  animation: tutGlow 2.4s ease-in-out infinite;
}
@keyframes tutGlow {
  0%, 100% {
    box-shadow: 0 8px 22px rgba(0,0,0,.5), 0 0 14px rgb(var(--rgb-violeta) / .28);
  }
  50% {
    box-shadow: 0 8px 22px rgba(0,0,0,.5), 0 0 30px rgb(var(--rgb-violeta) / .65);
  }
}
/* Anillo de sonar: sale del icono y se disuelve. Es lo que hace
   que el ojo vuelva ahí solo aunque estés mirando otra cosa. */
.icono.tut-destacado::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 1px solid rgb(var(--rgb-violeta) / .6);
  animation: tutSonar 2.4s cubic-bezier(.2,.7,.3,1) infinite;
  pointer-events: none;
}
@keyframes tutSonar {
  0%   { opacity: .85; transform: scale(1); }
  70%  { opacity: 0;   transform: scale(1.28); }
  100% { opacity: 0;   transform: scale(1.28); }
}

/* Rechazo: la app que no toca no regaña, solo niega con la cabeza.
   Movimiento corto + destello carmesí (el color del "ahora no"). */
.icono.tut-shake { animation: tutShake .45s cubic-bezier(.36,.07,.19,.97); }
@keyframes tutShake {
  0%, 100% { transform: translateX(0); }
  15% { transform: translateX(-4px); }
  30% { transform: translateX(4px); box-shadow: 0 0 18px rgb(var(--rgb-carmesi) / .45); }
  45% { transform: translateX(-3px); }
  60% { transform: translateX(3px); box-shadow: 0 0 12px rgb(var(--rgb-carmesi) / .3); }
  80% { transform: translateX(-1px); }
}

/* La barra de atención se oculta hasta que empieza la noche */
#atencion.tut-oculto { visibility: hidden; }
/* Reveal al dar las 23:00: el recurso escaso "se enciende" */
#atencion.tut-revelar { animation: tutRevelar 1s cubic-bezier(.2,.8,.2,1); }
@keyframes tutRevelar {
  0%   { opacity: 0; transform: scale(.5); box-shadow: 0 0 0 rgb(var(--rgb-carmesi) / 0); }
  55%  { opacity: 1; transform: scale(1.18); box-shadow: 0 0 34px rgb(var(--rgb-carmesi) / .75); }
  100% { opacity: 1; transform: scale(1); box-shadow: 0 0 0 rgb(var(--rgb-carmesi) / 0); }
}

/* --- Botón [?] señalado ---
   Antes se pintaba de rojo plano con !important y parecía un
   error del sistema. Ahora es un anillo violeta que respira. */
.vb-info.tut-parpadeo {
  color: #fff;
  background: rgb(var(--rgb-violeta) / .22);
  animation: tutParpadeo 1.8s ease-in-out infinite;
}
@keyframes tutParpadeo {
  0%, 100% { box-shadow: inset 0 0 0 1px rgb(var(--rgb-violeta) / .5), 0 0 10px rgb(var(--rgb-violeta) / .25); }
  50%      { box-shadow: inset 0 0 0 1px rgb(var(--rgb-violeta) / .9), 0 0 20px rgb(var(--rgb-violeta) / .65); }
}

/* --- Mezclador de la barra, cuando Tuk lo recuerda ---
   Mismo anillo violeta que el [?]: es "mira, esto existe". */
.tray-btn.tut-parpadeo {
  color: #fff;
  background: rgb(var(--rgb-violeta) / .22);
  border-radius: 6px;
  animation: tutParpadeo 1.8s ease-in-out infinite;
}

/* --- Botón [X] de la app que ya has terminado ---
   El tutorial te manda de app en app y las ventanas se apilan. Al
   cambiar de paso se marca la [X] de la anterior, porque cerrar
   ventanas también se aprende. Reutiliza tut-parpadeo, pero en
   carmesí: cerrar es "acabar con esto", no "ir hacia aquí". */
.vb-close.tut-parpadeo {
  color: #fff;
  background: rgb(var(--rgb-carmesi) / .28);
  animation: tutCerrar 1.6s ease-in-out infinite;
}
@keyframes tutCerrar {
  0%, 100% { box-shadow: inset 0 0 0 1px rgb(var(--rgb-carmesi) / .55), 0 0 10px rgb(var(--rgb-carmesi) / .3); }
  50%      { box-shadow: inset 0 0 0 1px rgb(var(--rgb-carmesi) / .95), 0 0 22px rgb(var(--rgb-carmesi) / .7); }
}

/* Elementos que el tutorial pide abrir: pestaña de Glim, barra de
   historias, o un DM concreto. Todos hablan en violeta. */
.gl-tab.tut-senal {
  color: #fff;
  animation: tutSenal 1.8s ease-in-out infinite;
}
@keyframes tutSenal {
  0%, 100% { box-shadow: inset 0 0 0 1px rgb(var(--rgb-violeta) / .45), 0 0 8px rgb(var(--rgb-violeta) / .2); }
  50%      { box-shadow: inset 0 0 0 1px rgb(var(--rgb-violeta) / .85), 0 0 18px rgb(var(--rgb-violeta) / .5); }
}

/* Barra de historias señalada: se enmarca entera y los aros giran
   más deprisa, para que se lea "esto de aquí arriba, ábrelo". */
.gl-historias.tut-senal {
  border-radius: 12px;
  animation: tutSenal 1.8s ease-in-out infinite;
}
.gl-historias.tut-senal .gl-hist:not(.vista) .gl-hist-aro::before {
  animation-duration: 1.6s;
}

/* UNA historia señalada.
   El marco de la fila entera dice "esta sección existe"; esto dice
   "esta de aquí". Tiene que ganarle al marco sin gritar, así que en
   vez de más borde se usa MOVIMIENTO: el aro late y el nombre se
   enciende. El ojo va al que se mueve. */
.gl-hist.tut-senal { animation: tutHist 1.5s ease-in-out infinite; }
.gl-hist.tut-senal .gl-hist-nom { color: #fff; font-weight: 600; opacity: 1; }
.gl-hist.tut-senal .gl-hist-aro {
  box-shadow: 0 0 0 2px var(--acento-violeta), 0 0 16px rgb(var(--rgb-violeta) / .55);
  border-radius: 50%;
}
@keyframes tutHist {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.08); }
}
/* Quien juegue con el movimiento reducido no se queda sin la pista:
   se le marca igual, solo que quieta. */
@media (prefers-reduced-motion: reduce) {
  .gl-hist.tut-senal { animation: none; transform: scale(1.06); }
}

/* Canal de Kord señalado (el privado de tuk, en el tutorial).
   Los MENSAJES DIRECTOS están al fondo de una columna de once
   entradas: sin esto, "te escribo por privado" deja al jugador
   buscando dónde. */
.kord-canal.tut-senal {
  border-radius: var(--radio);
  animation: tutSenal 1.8s ease-in-out infinite;
}
.kord-canal.tut-senal .kord-canal-nom { color: #fff; font-weight: 600; }

/* DMs de relleno señalados: el Día 1 son los únicos que hay y van
   atenuados por diseño, así que sin esto no se ven. */
.gl-dm-item.tut-senal {
  animation: tutSenal 1.8s ease-in-out infinite;
}
.gl-dm-item.secundaria.tut-senal .gl-dm-nom { color: #fff; font-weight: 600; }
.gl-dm-item.secundaria.tut-senal .dc-avatar { opacity: 1; }

/* ---- Chip de objetivo (barra de tareas) ----
   Deja de ser una pegatina con chincheta y pasa a ser una línea
   de misión de HUD: cristal, texto en Outfit y un LED que late.
   El 📌 que mete el JS se sustituye por ese LED desde aquí, sin
   tocar tutorial.js: se anula el emoji con font-size:0 y se
   dibuja el punto en el ::before. */
.tut-chip {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--fuente-ui);
  font-size: 12px;
  color: var(--texto);
  background: linear-gradient(180deg, rgb(var(--rgb-violeta) / .20), rgb(var(--rgb-violeta) / .05));
  border: 1px solid rgb(var(--rgb-violeta) / .45);
  padding: 7px 14px 7px 12px;
  border-radius: var(--radio-capsula);
  white-space: nowrap;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 0 16px rgb(var(--rgb-violeta) / .18);
  transition: box-shadow .3s ease, border-color .3s ease;
}
.tut-chip-ico {
  font-size: 0;                 /* oculta el 📌 sin tocar el JS */
  display: inline-flex;
  align-items: center;
}
.tut-chip-ico::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--acento-violeta);
  box-shadow: 0 0 8px rgb(var(--rgb-violeta) / .9);
  animation: tutLed 1.8s ease-in-out infinite;
}
@keyframes tutLed {
  0%, 100% { opacity: .45; box-shadow: 0 0 6px rgb(var(--rgb-violeta) / .5); }
  50%      { opacity: 1;   box-shadow: 0 0 14px rgb(var(--rgb-violeta) / 1); }
}
.tut-chip-txt {
  font-weight: 600;
  letter-spacing: .2px;
}

/* Al intentar abrir una app que no toca, el chip te recuerda cuál sí */
.tut-chip.tut-chip-flash { animation: tutChipFlash .7s cubic-bezier(.2,.8,.2,1); }
@keyframes tutChipFlash {
  0%, 100% { transform: none; border-color: rgb(var(--rgb-violeta) / .45); box-shadow: 0 0 16px rgb(var(--rgb-violeta) / .18); }
  30%      { transform: scale(1.06); border-color: rgb(var(--rgb-violeta) / .95); box-shadow: 0 0 26px rgb(var(--rgb-violeta) / .6); }
}

/* =========================================================
   BOTÓN [?] Y OVERLAY DE AYUDA
   ========================================================= */
.ventana-botones .vb-info { font-weight: 700; }
.ventana-botones .vb-info:hover { background: var(--acento-suave); color: #fff; }

.ayuda-overlay {
  position: absolute;
  inset: 0;
  z-index: 9500;
  background: rgba(4, 6, 10, .6);
  backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 30px;
  animation: aparecer .18s ease-out;
}

.ayuda-card {
  width: 460px;
  max-width: 100%;
  max-height: 100%;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--borde);
  border-radius: 14px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .6);
  animation: ayudaEntra .22s cubic-bezier(.2, .8, .2, 1);
}
@keyframes ayudaEntra {
  from { opacity: 0; transform: translateY(10px) scale(.98); }
  to   { opacity: 1; transform: none; }
}

/* Cabecera */
.ayuda-cab {
  display: flex; align-items: center; gap: 13px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--borde);
}
.ayuda-ico {
  width: 46px; height: 46px; flex: 0 0 auto;
  display: grid; place-items: center;
  font-size: 24px;
  background: var(--panel-alto);
  border-radius: 12px;
}
.ayuda-tit { flex: 1; min-width: 0; }
.ayuda-nombre { font-size: 17px; font-weight: 700; }
.ayuda-sub { font-size: 12px; color: var(--texto-tenue); }
.ayuda-x {
  background: none; border: none; color: var(--texto-tenue);
  font-size: 24px; line-height: 1; cursor: pointer; padding: 0 4px;
}
.ayuda-x:hover { color: var(--texto); }

/* Bloques */
.ayuda-bloque { padding: 14px 20px; border-bottom: 1px solid var(--borde); }
.ayuda-bloque:last-child { border-bottom: none; }
.ayuda-bloque-tit {
  font-size: 10px; font-weight: 700; letter-spacing: 1px;
  text-transform: uppercase; color: var(--texto-tenue);
  margin-bottom: 7px;
}
.ayuda-bloque-txt { font-size: 13px; line-height: 1.55; color: var(--texto); }

/* Coste */
.ayuda-coste-fila { display: flex; align-items: flex-start; gap: 12px; }
.ayuda-coste-puntos {
  flex: 0 0 auto;
  font-size: 16px; letter-spacing: 2px; color: var(--acento-suave);
  padding: 3px 10px; border-radius: 8px;
  background: var(--panel-alto);
  min-width: 54px; text-align: center;
}
.ayuda-coste-puntos.gratis {
  font-size: 11px; font-weight: 700; letter-spacing: .5px;
  color: #6cbf73; padding: 6px 10px;
}
.ayuda-coste-desc { font-size: 12.5px; line-height: 1.5; color: var(--texto); }

/* Personajes */
.ayuda-personajes { display: flex; flex-direction: column; gap: 8px; }
.ayuda-personaje { display: flex; align-items: center; gap: 11px; }
.ayuda-personaje-info { min-width: 0; }
.ayuda-personaje-nom { font-size: 13px; font-weight: 600; }
.ayuda-personaje-rol { font-size: 11px; color: var(--texto-tenue); }

/* Nota */
.ayuda-nota {
  padding: 12px 20px 18px;
  font-size: 12px; font-style: italic; line-height: 1.5;
  color: var(--texto-tenue);
}

/* ============================================================
   VELVET — "Dark Luxury"
   ------------------------------------------------------------
   Boutique erótica de alta gama: fondo profundo con brillos
   magenta / oro rosa, glassmorphism en tarjetas y paneles, y
   tipografía de boutique. Todo scoped bajo .app-velvet para que
   no afecte al resto del sistema operativo falso.
   ============================================================ */
.app-velvet {
  --vv-bg:        #0b0a10;
  --vv-bg2:       #120e17;
  --vv-magenta:   #d81b60;
  --vv-red:       #e53935;
  --vv-gold:      #ffb74d;
  --vv-rosa:      #f3a48b;   /* oro rosa */
  --vv-txt:       #f4eef2;
  --vv-txt-dim:   #a498a6;
  --vv-glass:     rgba(255,255,255,.045);
  --vv-glass-2:   rgba(255,255,255,.07);
  --vv-brd:       rgba(255,255,255,.10);
  --vv-brd-glow:  rgba(243,164,139,.45);

  display: flex;
  flex-direction: column;
  width: 100%;
  min-height: 0;
  color: var(--vv-txt);
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  background:
    radial-gradient(1100px 460px at 12% -12%, rgba(216,27,96,.20), transparent 60%),
    radial-gradient(820px 460px at 104% -6%, rgba(255,183,77,.11), transparent 55%),
    radial-gradient(760px 620px at 88% 118%, rgba(229,57,53,.14), transparent 60%),
    linear-gradient(158deg, var(--vv-bg2), var(--vv-bg));
}
.app-velvet ::-webkit-scrollbar { width: 10px; }
.app-velvet ::-webkit-scrollbar-thumb {
  background: linear-gradient(var(--vv-magenta), var(--vv-red));
  border-radius: 10px; border: 3px solid transparent; background-clip: padding-box;
}

/* ---------------- Barra superior ---------------- */
.app-velvet .vv-nav {
  display: flex; align-items: center; gap: 16px;
  padding: 14px 22px;
  border-bottom: 1px solid var(--vv-brd);
  background: linear-gradient(180deg, rgba(0,0,0,.35), rgba(0,0,0,.05));
  backdrop-filter: blur(8px);
}
.app-velvet .vv-brand { display: flex; flex-direction: column; line-height: 1; }
.app-velvet .vv-logo {
  font-family: "Bodoni MT", "Didot", "Playfair Display", Georgia, serif;
  font-size: 26px; font-weight: 700; letter-spacing: 6px;
  background: linear-gradient(120deg, #fff 10%, var(--vv-rosa) 55%, var(--vv-gold) 90%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--vv-gold);
}
.app-velvet .vv-tagline {
  font-size: 9.5px; letter-spacing: 3px; text-transform: uppercase;
  color: var(--vv-txt-dim); margin-top: 5px;
}
.app-velvet .vv-tabs { display: flex; gap: 6px; margin-left: 8px; }
.app-velvet .vv-tab {
  display: inline-flex; align-items: center; gap: 6px;
  background: transparent; border: 1px solid transparent;
  color: var(--vv-txt-dim); font-size: 12.5px; letter-spacing: .3px;
  padding: 8px 14px; border-radius: 999px; transition: .18s;
}
.app-velvet .vv-tab .vv-tab-ico { font-size: 12px; opacity: .9; }
.app-velvet .vv-tab:hover { color: var(--vv-txt); background: var(--vv-glass); }
.app-velvet .vv-tab.activo {
  color: #fff; border-color: var(--vv-brd-glow);
  background: linear-gradient(180deg, rgba(216,27,96,.30), rgba(216,27,96,.10));
  box-shadow: 0 0 18px rgba(216,27,96,.28);
}
.app-velvet .vv-cartera { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.app-velvet .vv-dinero {
  font-size: 13px; font-weight: 600; color: var(--vv-txt);
  background: var(--vv-glass); border: 1px solid var(--vv-brd);
  padding: 7px 13px; border-radius: 999px; white-space: nowrap;
}
.app-velvet .vv-vip-chip {
  font-size: 10px; font-weight: 800; letter-spacing: 1.5px; color: #1a1206;
  background: linear-gradient(120deg, var(--vv-gold), #ffd89e);
  padding: 6px 11px; border-radius: 999px;
  box-shadow: 0 0 16px rgba(255,183,77,.45);
}

/* ---------------- Zona con scroll ---------------- */
.app-velvet .vv-scroll { flex: 1; min-height: 0; overflow-y: auto; }
.app-velvet .vv-cuerpo { padding: 20px 22px 26px; }

/* ---------------- Banner Velvet Black ---------------- */
.app-velvet .vv-banner {
  position: relative; overflow: hidden;
  border: 1px solid var(--vv-brd);
  border-radius: 16px; padding: 18px 20px; margin-bottom: 18px;
  background:
    linear-gradient(120deg, rgba(20,16,10,.72), rgba(10,9,14,.72));
  backdrop-filter: blur(14px);
  box-shadow: 0 18px 50px rgba(0,0,0,.45);
}
.app-velvet .vv-banner::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(600px 200px at 90% 0%, rgba(255,183,77,.14), transparent 60%);
  pointer-events: none;
}
.app-velvet .vv-banner.activo {
  border-color: rgba(255,183,77,.5);
  box-shadow: 0 18px 50px rgba(0,0,0,.5), 0 0 26px rgba(255,183,77,.18) inset;
}
.app-velvet .vv-banner-main { display: flex; align-items: center; gap: 16px; position: relative; }
.app-velvet .vv-banner-sello {
  font-size: 12px; font-weight: 800; letter-spacing: 2px; white-space: nowrap;
  color: var(--vv-gold);
  border: 1px solid rgba(255,183,77,.4); border-radius: 10px;
  padding: 10px 12px; background: rgba(0,0,0,.35);
}
.app-velvet .vv-banner-info { flex: 1; min-width: 0; }
.app-velvet .vv-banner-title {
  font-family: "Bodoni MT", "Didot", Georgia, serif;
  font-size: 19px; font-weight: 700; letter-spacing: .5px; color: #fff;
}
.app-velvet .vv-banner-sub { font-size: 12px; color: var(--vv-txt-dim); margin-top: 3px; }
.app-velvet .vv-estado {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
  font-size: 11.5px; font-weight: 600; padding: 7px 12px; border-radius: 999px;
  border: 1px solid var(--vv-brd);
}
.app-velvet .vv-estado-dot { width: 8px; height: 8px; border-radius: 50%; }
.app-velvet .vv-estado.vip {
  color: var(--vv-gold); border-color: rgba(255,183,77,.5); background: rgba(255,183,77,.08);
}
.app-velvet .vv-estado.vip .vv-estado-dot {
  background: var(--vv-gold); box-shadow: 0 0 8px var(--vv-gold);
}
.app-velvet .vv-estado.normal { color: var(--vv-txt-dim); }
.app-velvet .vv-estado.normal .vv-estado-dot { background: var(--vv-txt-dim); }

.app-velvet .vv-banner-meta {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-top: 15px; padding-top: 14px; border-top: 1px solid var(--vv-brd);
  position: relative;
}
.app-velvet .vv-cuota { display: flex; align-items: center; gap: 10px; }
.app-velvet .vv-cuota-lab { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--vv-txt-dim); }
.app-velvet .vv-cuota-val { font-size: 15px; font-weight: 700; color: #fff; }
.app-velvet .vv-cuota-dots { display: flex; gap: 5px; }
.app-velvet .vv-cuota-dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: rgba(255,255,255,.14); border: 1px solid var(--vv-brd);
}
.app-velvet .vv-cuota-dot.gastado {
  background: linear-gradient(var(--vv-magenta), var(--vv-red));
  border-color: transparent; box-shadow: 0 0 8px rgba(216,27,96,.6);
}
.app-velvet .vv-cuota.agotada .vv-cuota-val { color: var(--vv-rosa); }
.app-velvet .vv-banner-cta { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.app-velvet .vv-banner-precio { font-size: 18px; font-weight: 800; color: #fff; }
.app-velvet .vv-banner-precio small { font-size: 11px; font-weight: 500; color: var(--vv-txt-dim); }
.app-velvet .vv-banner-btn {
  border: none; color: #1a1206; font-weight: 800; letter-spacing: .5px;
  padding: 11px 20px; border-radius: 999px;
  background: linear-gradient(120deg, var(--vv-gold), #ffd89e);
  box-shadow: 0 8px 24px rgba(255,183,77,.35); transition: .18s;
}
.app-velvet .vv-banner-btn:hover { transform: translateY(-1px); box-shadow: 0 12px 30px rgba(255,183,77,.5); }

/* ---------------- "Comprando para" ---------------- */
.app-velvet .vv-shopfor {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: 16px;
}
.app-velvet .vv-shopfor-lab {
  font-size: 11px; text-transform: uppercase; letter-spacing: 1.5px; color: var(--vv-txt-dim);
}
.app-velvet .vv-shopfor-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.app-velvet .vv-shopfor-chip {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--vv-glass); border: 1px solid var(--vv-brd);
  color: var(--vv-txt-dim); font-size: 12px; padding: 5px 12px 5px 5px;
  border-radius: 999px; transition: .18s;
}
.app-velvet .vv-shopfor-chip .dc-avatar { width: 26px; height: 26px; }
.app-velvet .vv-shopfor-chip:hover { color: var(--vv-txt); border-color: var(--vv-brd-glow); }
.app-velvet .vv-shopfor-chip.activo {
  color: #fff; border-color: var(--vv-rosa);
  background: linear-gradient(180deg, rgba(243,164,139,.22), rgba(243,164,139,.06));
  box-shadow: 0 0 16px rgba(243,164,139,.3);
}
.app-velvet .vv-shopfor-clear {
  background: none; border: none; color: var(--vv-txt-dim);
  font-size: 11.5px; text-decoration: underline; padding: 4px;
}
.app-velvet .vv-shopfor-clear:hover { color: var(--vv-rosa); }

/* El regalo en el momento justo: recordatorio bajo «Comprando para» */
.app-velvet .vv-ocasion {
  margin: -6px 0 16px; padding: 10px 14px; border-radius: 12px;
  border: 1px solid rgba(255,183,77,.35);
  background: linear-gradient(180deg, rgba(255,183,77,.12), rgba(255,183,77,.03));
  font-size: 12.5px; line-height: 1.45; color: var(--vv-txt);
}
.app-velvet .vv-ocasion-tit {
  font-size: 11px; text-transform: uppercase; letter-spacing: 1.2px;
  color: var(--vv-gold); margin-bottom: 3px;
}
.app-velvet .vv-ocasion-plazo { color: var(--vv-txt-dim); margin-top: 3px; font-style: italic; }

/* Pestaña Velvet Black: dorada aunque no esté seleccionada */
.app-velvet .vv-cat.vv-cat-black { border-color: rgba(212,175,106,.45); color: #d4af6a; }
.app-velvet .vv-cat.vv-cat-black .vv-cat-lock {
  font-size: 10px; letter-spacing: .5px; opacity: .8; margin-left: 2px;
}

/* ---------------- Filtros de categoría ---------------- */
.app-velvet .vv-cats { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 18px; }
.app-velvet .vv-cat {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--vv-glass); border: 1px solid var(--vv-brd);
  color: var(--vv-txt-dim); font-size: 12.5px; letter-spacing: .3px;
  padding: 9px 15px; border-radius: 12px; transition: .18s;
}
.app-velvet .vv-cat .vv-cat-ico { font-size: 15px; }
.app-velvet .vv-cat:hover {
  color: var(--vv-txt); border-color: var(--vv-brd-glow);
  background: var(--vv-glass-2); box-shadow: 0 0 18px rgba(243,164,139,.2);
}
.app-velvet .vv-cat.activo {
  color: #fff; border-color: transparent;
  background: linear-gradient(120deg, var(--vv-magenta), var(--vv-red));
  box-shadow: 0 8px 24px rgba(216,27,96,.4);
}

/* ---------------- Rejilla de productos ---------------- */
.app-velvet .vv-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 16px;
}
.app-velvet .vv-prod {
  position: relative; display: flex; flex-direction: column; overflow: hidden;
  border: 1px solid var(--vv-brd); border-radius: 16px;
  background: var(--vv-glass); backdrop-filter: blur(12px);
  box-shadow: 0 12px 34px rgba(0,0,0,.4);
  transition: transform .2s, box-shadow .2s, border-color .2s;
}
.app-velvet .vv-prod:hover {
  transform: translateY(-4px); border-color: var(--vv-brd-glow);
  box-shadow: 0 20px 46px rgba(0,0,0,.55), 0 0 26px rgba(243,164,139,.22);
}
.app-velvet .vv-prod.deseo { border-color: rgba(216,27,96,.5); }
.app-velvet .vv-prod.deseo:hover { box-shadow: 0 20px 46px rgba(0,0,0,.55), 0 0 26px rgba(216,27,96,.4); }
.app-velvet .vv-prod-deseo {
  position: absolute; top: 10px; left: 10px; z-index: 2;
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10px; font-weight: 700; letter-spacing: .4px; color: #fff;
  background: linear-gradient(120deg, var(--vv-magenta), var(--vv-red));
  padding: 5px 10px; border-radius: 999px; box-shadow: 0 4px 14px rgba(216,27,96,.5);
}
.app-velvet .vv-prod-deseo span { font-size: 11px; }
.app-velvet .vv-prod-img {
  height: 160px;
  width: 100%;
  position: relative;
  overflow: hidden;
  background: #0d0a14;
  border-bottom: 1px solid var(--vv-brd);
  display: flex;
  align-items: center;
  justify-content: center;
}
.app-velvet .vv-prod-cuerpo {
  position: relative; z-index: 1; flex: 1;
  display: flex; flex-direction: column; gap: 8px; padding: 14px;
}
.app-velvet .vv-prod-nom { font-size: 14px; font-weight: 700; color: #fff; line-height: 1.25; }
.app-velvet .vv-prod-desc { font-size: 11.5px; color: var(--vv-txt-dim); line-height: 1.5; flex: 1; }
.app-velvet .vv-prod-fila { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 4px; }
.app-velvet .vv-prod-precio {
  font-size: 16px; font-weight: 800;
  background: linear-gradient(120deg, #fff, var(--vv-gold));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  color: var(--vv-gold);
}
.app-velvet .vv-prod-btn {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--vv-brd-glow); color: #fff; font-size: 12px; font-weight: 600;
  padding: 8px 13px; border-radius: 999px;
  background: linear-gradient(180deg, rgba(243,164,139,.18), rgba(243,164,139,.05));
  transition: .18s;
}
.app-velvet .vv-prod-btn:hover {
  background: linear-gradient(120deg, var(--vv-magenta), var(--vv-red));
  border-color: transparent; box-shadow: 0 6px 20px rgba(216,27,96,.45);
}

/* Slot de imagen dentro de Velvet (anula el min-width del media-slot) */
.app-velvet .vv-slot {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #120e1a;
}
.app-velvet .vv-slot img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 8px; }
.app-velvet .vv-slot .media-slot {
  min-width: 0; width: 100%; height: 100%; border-radius: 10px;
  border-color: var(--vv-brd); background: rgba(0,0,0,.25); padding: 10px;
}
.app-velvet .vv-slot .media-slot-id { font-size: 9px; color: var(--vv-txt-dim); }

/* ---------------- Modal de envío (2 pasos) ---------------- */
.app-velvet .vv-envio {
  position: absolute; inset: 0; z-index: 60;
  display: grid; place-items: center; padding: 20px;
  background: rgba(6,5,9,.72); backdrop-filter: blur(6px);
  animation: vv-fade .18s ease;
}
@keyframes vv-fade { from { opacity: 0; } to { opacity: 1; } }
.app-velvet .vv-envio-caja {
  width: 440px; max-width: 100%; max-height: 100%; overflow-y: auto;
  border: 1px solid var(--vv-brd-glow); border-radius: 18px;
  background: linear-gradient(160deg, rgba(24,18,26,.96), rgba(11,10,16,.96));
  box-shadow: 0 30px 80px rgba(0,0,0,.6), 0 0 30px rgba(243,164,139,.14);
  animation: vv-pop .2s ease;
}
@keyframes vv-pop { from { transform: translateY(10px) scale(.98); } to { transform: none; } }
.app-velvet .vv-envio-cab {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px 12px; font-size: 15px; color: #fff;
}
.app-velvet .vv-envio-cab b { font-family: "Bodoni MT", "Didot", Georgia, serif; letter-spacing: .5px; }
.app-velvet .vv-envio-x {
  background: none; border: none; color: var(--vv-txt-dim); font-size: 22px; line-height: 1; padding: 0 4px;
}
.app-velvet .vv-envio-x:hover { color: var(--vv-rosa); }

.app-velvet .vv-envio-hero {
  display: flex; align-items: center; gap: 14px; margin: 0 18px 14px;
  padding: 12px; border-radius: 14px;
  background: var(--vv-glass); border: 1px solid var(--vv-brd);
}
.app-velvet .vv-envio-hero-img { width: 64px; height: 64px; flex: none; }
.app-velvet .vv-envio-hero-nom { font-size: 14px; font-weight: 700; color: #fff; }
.app-velvet .vv-envio-hero-precio {
  font-size: 14px; font-weight: 800; margin-top: 3px; color: var(--vv-gold);
}
.app-velvet .vv-envio-cupo {
  margin: 0 18px 12px; font-size: 11.5px; color: var(--vv-txt-dim);
}
.app-velvet .vv-envio-chicas {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; padding: 0 18px 18px;
}
.app-velvet .vv-envio-chica {
  position: relative; display: flex; align-items: center; gap: 10px;
  background: var(--vv-glass); border: 1px solid var(--vv-brd);
  color: var(--vv-txt); font-size: 13px; padding: 8px 10px; border-radius: 12px; transition: .16s;
}
.app-velvet .vv-envio-chica:hover { border-color: var(--vv-brd-glow); background: var(--vv-glass-2); }
.app-velvet .vv-envio-chica.sugerida { border-color: var(--vv-rosa); box-shadow: 0 0 14px rgba(243,164,139,.25); }
.app-velvet .vv-envio-chica .dc-avatar { width: 32px; height: 32px; flex: none; }
.app-velvet .vv-envio-chica-nom { flex: 1; text-align: left; }
.app-velvet .vv-envio-chica.bloqueada { opacity: .45; cursor: not-allowed; filter: grayscale(.6); }
.app-velvet .vv-envio-proximamente { font-size: 11px; white-space: nowrap; }
.app-velvet .vv-envio-deseo { color: var(--vv-magenta); font-size: 15px; text-shadow: 0 0 10px rgba(216,27,96,.7); }

/* Paso 2: confirmación */
.app-velvet .vv-conf { display: flex; align-items: center; gap: 14px; margin: 0 18px 14px; }
.app-velvet .vv-conf-foto .dc-avatar {
  width: 76px; height: 76px; font-size: 28px;
  box-shadow: 0 0 0 2px rgba(243,164,139,.4), 0 8px 24px rgba(0,0,0,.5);
}
.app-velvet .vv-conf-info { min-width: 0; }
.app-velvet .vv-conf-para { font-size: 15px; font-weight: 700; color: #fff; }
.app-velvet .vv-conf-que { font-size: 12.5px; color: var(--vv-txt-dim); margin-top: 3px; }
.app-velvet .vv-conf-deseo {
  display: inline-flex; align-items: center; gap: 5px; margin-top: 7px;
  font-size: 11px; font-weight: 700; color: #fff;
  background: linear-gradient(120deg, var(--vv-magenta), var(--vv-red));
  padding: 4px 9px; border-radius: 999px;
}
.app-velvet .vv-conf-plazo {
  margin: 0 18px 16px; padding: 11px 14px; border-radius: 12px;
  font-size: 12.5px; color: var(--vv-txt);
  background: rgba(0,0,0,.3); border: 1px solid var(--vv-brd);
}
.app-velvet .vv-conf-plazo em { color: var(--vv-txt-dim); font-style: normal; }
.app-velvet .vv-conf-plazo.rapido { border-color: rgba(255,183,77,.5); background: rgba(255,183,77,.08); }
.app-velvet .vv-conf-plazo-ico { margin-right: 6px; }
.app-velvet .vv-conf-acciones { display: flex; gap: 10px; padding: 0 18px 20px; }
.app-velvet .vv-conf-volver {
  background: var(--vv-glass); border: 1px solid var(--vv-brd); color: var(--vv-txt-dim);
  font-size: 13px; padding: 12px 16px; border-radius: 12px; transition: .16s;
}
.app-velvet .vv-conf-volver:hover { color: var(--vv-txt); border-color: var(--vv-brd-glow); }
.app-velvet .vv-conf-comprar {
  flex: 1; border: none; color: #fff; font-size: 13.5px; font-weight: 700; letter-spacing: .3px;
  padding: 12px 16px; border-radius: 12px;
  background: linear-gradient(120deg, var(--vv-magenta), var(--vv-red));
  box-shadow: 0 10px 28px rgba(216,27,96,.4); transition: .16s;
}
.app-velvet .vv-conf-comprar:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 14px 34px rgba(216,27,96,.55); }
.app-velvet .vv-conf-comprar:disabled { background: rgba(255,255,255,.08); color: var(--vv-txt-dim); box-shadow: none; cursor: not-allowed; }

/* ---------------- Wishlists ---------------- */
.app-velvet .vv-wl-intro {
  font-size: 13px; font-style: italic; color: var(--vv-txt-dim); margin-bottom: 16px;
}
.app-velvet .vv-wl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.app-velvet .vv-wl-card {
  border: 1px solid var(--vv-brd); border-radius: 16px; padding: 14px;
  background: var(--vv-glass); backdrop-filter: blur(12px); box-shadow: 0 12px 34px rgba(0,0,0,.4);
}
.app-velvet .vv-wl-cab { display: flex; align-items: center; gap: 11px; margin-bottom: 12px; }
.app-velvet .vv-wl-cab .dc-avatar { width: 40px; height: 40px; flex: none; }
.app-velvet .vv-wl-info { flex: 1; min-width: 0; }
.app-velvet .vv-wl-nom { font-size: 14px; font-weight: 700; color: #fff; }
.app-velvet .vv-wl-pista { font-size: 11.5px; font-style: italic; color: var(--vv-txt-dim); line-height: 1.4; margin-top: 2px; }
.app-velvet .vv-wl-bonus {
  flex: none; font-size: 11px; font-weight: 700; color: var(--vv-magenta); white-space: nowrap;
  border: 1px solid rgba(216,27,96,.4); border-radius: 999px; padding: 4px 9px; background: rgba(216,27,96,.08);
}
.app-velvet .vv-wl-items { display: flex; flex-direction: column; gap: 8px; }
.app-velvet .vv-wl-item {
  display: flex; align-items: center; gap: 10px; font-size: 12.5px; color: var(--vv-txt);
  padding: 7px 9px; border-radius: 10px; background: rgba(0,0,0,.22); border: 1px solid var(--vv-brd);
}
.app-velvet .vv-wl-miniatura { width: 42px; height: 42px; flex: none; }

/* ---------------- Pedidos ---------------- */
.app-velvet .vv-pedido {
  display: flex; align-items: center; gap: 12px; margin-bottom: 10px;
  border: 1px solid var(--vv-brd); border-radius: 14px; padding: 12px 14px;
  background: var(--vv-glass); backdrop-filter: blur(10px);
}
.app-velvet .vv-pedido .dc-avatar { width: 40px; height: 40px; flex: none; }
.app-velvet .vv-pedido-info { flex: 1; min-width: 0; }
.app-velvet .vv-pedido-nom { font-size: 13.5px; font-weight: 600; color: #fff; }
.app-velvet .vv-pedido-est { font-size: 11.5px; color: var(--vv-rosa); margin-top: 2px; }
.app-velvet .vv-pedido-deseo {
  flex: none; font-size: 11px; font-weight: 700; color: #fff;
  background: linear-gradient(120deg, var(--vv-magenta), var(--vv-red));
  padding: 4px 10px; border-radius: 999px;
}
.app-velvet .vv-nada {
  text-align: center; color: var(--vv-txt-dim); font-size: 13.5px; line-height: 1.7;
  padding: 60px 20px;
}
.app-velvet .vv-nada-ico { display: block; font-size: 40px; margin-bottom: 12px; opacity: .8; }

/* ---------------- Selector de color (swatches) ---------------- */
.app-velvet .vv-colores { display: flex; gap: 7px; margin: 2px 0 2px; }
.app-velvet .vv-color {
  width: 27px; height: 27px; display: grid; place-items: center;
  font-size: 13px; line-height: 1; border-radius: 50%;
  background: rgba(0,0,0,.32); border: 1px solid var(--vv-brd);
  transition: transform .14s, box-shadow .14s, border-color .14s;
}
.app-velvet .vv-color:hover { transform: scale(1.12); border-color: var(--vv-brd-glow); }
.app-velvet .vv-color.activo {
  border-color: var(--sw, var(--vv-rosa));
  box-shadow: 0 0 0 2px var(--sw, var(--vv-rosa)), 0 0 12px var(--sw, rgba(243,164,139,.6));
}

/* ---------------- Categoría "Próximamente" ---------------- */
.app-velvet .vv-cat.bloqueado { opacity: .9; }
.app-velvet .vv-cat-lock {
  font-size: 9.5px; font-weight: 700; letter-spacing: .3px; color: var(--vv-gold);
  background: rgba(0,0,0,.4); border: 1px solid rgba(255,183,77,.35);
  padding: 2px 7px; border-radius: 999px; margin-left: 3px; white-space: nowrap;
}
.app-velvet .vv-cat.bloqueado.activo {
  color: var(--vv-gold); border-color: rgba(255,183,77,.45);
  background: linear-gradient(120deg, rgba(60,50,22,.55), rgba(30,25,14,.55));
  box-shadow: none;
}

/* ---------------- Tarjeta de producto bloqueada ---------------- */
.app-velvet .vv-prod.bloqueado { opacity: .96; }
.app-velvet .vv-prod.bloqueado:hover {
  transform: none; border-color: var(--vv-brd);
  box-shadow: 0 12px 34px rgba(0,0,0,.4);
}
.app-velvet .vv-prod-lock {
  height: 160px; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; text-align: center; padding: 16px; border-bottom: 1px solid var(--vv-brd);
  background:
    repeating-linear-gradient(45deg, rgba(0,0,0,.34) 0 11px, rgba(255,255,255,.02) 11px 22px);
}
.app-velvet .vv-prod-lock-ico { font-size: 30px; opacity: .85; }
.app-velvet .vv-prod-lock-txt {
  font-size: 11px; font-weight: 600; color: var(--vv-gold); line-height: 1.4; max-width: 180px;
}
.app-velvet .vv-prod-btn.bloqueado {
  border-color: var(--vv-brd); color: var(--vv-txt-dim);
  background: rgba(255,255,255,.05); cursor: not-allowed;
}
.app-velvet .vv-prod-btn.bloqueado:hover { background: rgba(255,255,255,.05); box-shadow: none; }

/* ============================================================
   CORREO — cliente de email (sobrio a propósito)
   ------------------------------------------------------------
   Utilitario, no glamuroso: es el "ruido de fondo de una vida
   que va bien". Lista a la izquierda, lectura a la derecha.
   ============================================================ */
.app-correo { display: flex; width: 100%; height: 100%; background: var(--fondo-2); color: var(--texto); }

.app-correo .co-lista {
  width: 280px; flex: none; display: flex; flex-direction: column;
  border-right: 1px solid var(--borde); background: var(--panel);
}
.app-correo .co-cabecera {
  padding: 14px 16px; font-weight: 700; font-size: 14px;
  border-bottom: 1px solid var(--borde);
}
.app-correo .co-items { flex: 1; overflow-y: auto; }
.app-correo .co-item {
  display: block; width: 100%; text-align: left;
  padding: 12px 16px; border: none; border-bottom: 1px solid var(--borde);
  background: transparent; color: var(--texto);
}
.app-correo .co-item:hover { background: var(--panel-alto); }
.app-correo .co-item.activo { background: var(--panel-alto); box-shadow: inset 3px 0 0 var(--acento); }
.app-correo .co-item-de {
  font-size: 12.5px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.app-correo .co-item.nuevo .co-item-de { font-weight: 800; }
.app-correo .co-item.nuevo .co-item-de::before {
  content: '●'; color: var(--acento); font-size: 10px; margin-right: 6px; vertical-align: middle;
}
.app-correo .co-item-asunto {
  font-size: 12px; color: var(--texto-tenue); margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.app-correo .co-nada, .app-correo .co-vacio { padding: 24px 16px; color: var(--texto-tenue); font-size: 13px; }

.app-correo .co-lectura { flex: 1; min-width: 0; overflow-y: auto; padding: 22px 26px; }
.app-correo .co-asunto { margin: 0 0 8px; font-size: 18px; }
.app-correo .co-de { font-size: 12.5px; color: var(--texto-tenue); display: flex; align-items: center; gap: 10px; }
.app-correo .co-fecha {
  margin-left: auto; font-size: 11px; color: var(--texto-tenue);
  border: 1px solid var(--borde); border-radius: 999px; padding: 2px 8px;
}
.app-correo .co-sep { height: 1px; background: var(--borde); margin: 14px 0 18px; }
.app-correo .co-parrafo { font-size: 13.5px; line-height: 1.6; color: var(--texto); margin: 0 0 12px; }

/* Acciones (respuestas interactivas para guion) */
.app-correo .co-acciones {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--borde);
}
.app-correo .co-accion {
  background: var(--acento); color: #fff; border: none;
  padding: 9px 15px; border-radius: var(--radio); font-size: 12.5px; font-weight: 600;
}
.app-correo .co-accion:hover:not(:disabled) { background: var(--acento-suave); }
.app-correo .co-accion:disabled, .app-correo .co-accion.hecha {
  background: var(--panel-alto); color: var(--texto-tenue); cursor: default;
}
.app-correo .co-accion-resp { font-style: italic; color: var(--texto-tenue); margin-top: 12px; }

/* ============================================================
   LOGROS — toast flotante + app de Trofeos
   ============================================================ */
#logro-toasts {
  position: absolute; right: 18px; bottom: 60px; z-index: 9000;
  display: flex; flex-direction: column; gap: 10px; pointer-events: none;
}
.logro-toast {
  display: flex; align-items: center; gap: 12px; width: 300px; max-width: 80vw;
  background: linear-gradient(135deg, #2a2140, #171b24);
  border: 1px solid #c9a227; border-radius: 12px; padding: 12px 14px;
  box-shadow: 0 12px 40px rgba(0,0,0,.6), 0 0 20px rgba(201,162,39,.25);
  transform: translateX(120%); opacity: 0;
  transition: transform .35s cubic-bezier(.2,.9,.3,1.2), opacity .35s;
}
.logro-toast.entra { transform: none; opacity: 1; }
.logro-toast-ico {
  font-size: 26px; width: 44px; height: 44px; flex: none;
  display: grid; place-items: center; border-radius: 10px;
  background: rgba(201,162,39,.15); border: 1px solid rgba(201,162,39,.5);
}
.logro-toast-cab { font-size: 10px; text-transform: uppercase; letter-spacing: 1.5px; color: #e8c86a; }
.logro-toast-tit { font-size: 14px; font-weight: 700; color: #fff; margin-top: 2px; }

.app-trofeos { display: flex; flex-direction: column; width: 100%; height: 100%; background: var(--fondo-2); color: var(--texto); }
.tr-cab { display: flex; align-items: baseline; justify-content: space-between; padding: 16px 18px 8px; }
.tr-cab-tit { font-size: 16px; font-weight: 700; }
.tr-cab-cont { font-size: 13px; color: var(--texto-tenue); }
.tr-barra { height: 8px; margin: 0 18px 6px; background: var(--panel); border: 1px solid var(--borde); border-radius: 6px; overflow: hidden; }
.tr-barra-relleno { height: 100%; width: 0; background: linear-gradient(90deg, #c9a227, #e8c86a); transition: width .4s; }
.tr-zona { flex: 1; overflow-y: auto; padding: 10px 18px 18px; }
.tr-grupo { margin-bottom: 16px; }
.tr-grupo-tit { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--texto-tenue); margin: 6px 0 8px; }
.tr-item { display: flex; align-items: center; gap: 12px; padding: 10px 12px; margin-bottom: 8px; border: 1px solid var(--borde); border-radius: 10px; background: var(--panel); }
.tr-item.bloqueado { opacity: .55; }
.tr-item.hecho { border-color: rgba(201,162,39,.5); background: linear-gradient(135deg, rgba(201,162,39,.10), var(--panel)); }
.tr-item-ico { font-size: 22px; width: 40px; height: 40px; flex: none; display: grid; place-items: center; border-radius: 8px; background: rgba(0,0,0,.25); }
.tr-item.hecho .tr-item-ico { background: rgba(201,162,39,.18); }
.tr-item-nom { font-size: 13.5px; font-weight: 700; color: #fff; }
.tr-item-desc { font-size: 11.5px; color: var(--texto-tenue); margin-top: 2px; line-height: 1.4; }

/* ============================================================
   GUARDAR / CARGAR — panel de ranuras
   ============================================================ */
.app-guardado { display: flex; flex-direction: column; width: 100%; height: 100%; background: var(--fondo-2); color: var(--texto); }
.gu-cab { padding: 14px 18px; font-weight: 700; font-size: 14px; border-bottom: 1px solid var(--borde); }
.gu-zona { flex: 1; overflow-y: auto; padding: 14px 18px; display: flex; flex-direction: column; gap: 10px; }
.gu-slot { border: 1px solid var(--borde); border-radius: 12px; padding: 12px 14px; background: var(--panel); }
.gu-slot.auto { border-color: rgba(90,150,255,.4); }
.gu-slot.vacia { opacity: .78; }
.gu-slot-top { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.gu-slot-nom { font-size: 13.5px; font-weight: 700; color: #fff; }
/* La fecha empujada a la derecha; antes lo hacía el space-between,
   pero ahora entre medias va el lápiz de renombrar. */
.gu-slot-fecha { margin-left: auto; }

/* Un nombre puesto por el jugador se distingue del «Ranura 3» de
   fábrica: si no, no sabes cuáles has bautizado ya. */
/* Era esmeralda, y el esmeralda es de Wisp: la biblia dice que
   cada app habla en su color y que el violeta es el del sistema.
   Guardar/Cargar es una utilidad del sistema, no una app. */
.gu-slot-nom.propio { color: var(--acento-violeta); }
.gu-slot-nom.editable { cursor: text; }
.gu-slot-nom.editable:hover { text-decoration: underline dotted rgba(255,255,255,.35); }

/* Siempre visible. Antes estaba casi transparente hasta pasar el ratón
   y el jugador no sabía que se podía renombrar. Sigue siendo
   secundario (pequeño, sin relleno) para no competir con Cargar y
   Sobrescribir, pero se lee. */
.gu-renombrar {
  background: transparent;
  border: 1px solid rgba(255,255,255,.14);
  color: var(--texto-tenue);
  font-family: var(--fuente-ui);
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  padding: 4px 9px;
  border-radius: 999px;
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.gu-renombrar:hover {
  color: var(--texto);
  border-color: var(--acento-violeta);
  background: rgb(var(--rgb-violeta, 167 139 250) / .12);
}

.gu-slot-input {
  flex: 1;
  min-width: 0;
  background: rgba(0,0,0,.35);
  border: 1px solid var(--acento-violeta);
  border-radius: var(--radio);
  color: #fff;
  font-family: var(--fuente-ui);
  font-size: 13.5px;
  font-weight: 700;
  padding: 4px 8px;
  outline: none;
}
.gu-slot-input::placeholder { color: var(--texto-tenue); font-weight: 400; }
.gu-slot-fecha { font-size: 11px; color: var(--texto-tenue); }
.gu-slot-det { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; min-height: 22px; }
.gu-vacia-txt { font-size: 12.5px; color: var(--texto-tenue); }
.gu-corrupta { font-size: 12.5px; color: #f7a1b4; }
.gu-chip { font-size: 11.5px; color: var(--texto); background: rgba(0,0,0,.25); border: 1px solid var(--borde); border-radius: 999px; padding: 3px 9px; }
.gu-slot-acc { display: flex; gap: 8px; }
.gu-pie { display: flex; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--borde); }
/* Edición online: violeta, la voz del sistema */
.gu-nota-online {
  margin: 0;
  padding: 10px 18px;
  border-top: 1px solid var(--borde);
  font-size: 12px;
  line-height: 1.5;
  color: var(--acento-violeta);
}
.gu-btn { border: 1px solid var(--borde); background: var(--panel-alto); color: var(--texto); font-size: 12.5px; font-weight: 600; padding: 8px 13px; border-radius: 8px; }
.gu-btn:hover:not(:disabled) { border-color: var(--acento-suave); }
.gu-btn:disabled { opacity: .4; cursor: default; }
.gu-btn-guardar { background: var(--acento); color: #fff; border-color: transparent; }
.gu-btn-cargar { background: #3b3572; color: #fff; border-color: transparent; }
.gu-btn-borrar { margin-left: auto; }
.gu-btn-sec { flex: 1; }

/* ============================================================
   VAULT — la galería privada (src/apps/vault.js)
   La meta del juego: completar la colección al 100%.
   ============================================================ */
.app-vault { display: flex; height: 100%; min-height: 0; }

.vt-lateral {
  width: 208px; flex: none;
  display: flex; flex-direction: column;
  background: rgba(0,0,0,.22);
  border-right: 1px solid var(--borde);
  min-height: 0;
}

/* --- Bloque de progreso global --- */
.vt-progreso { padding: 14px 12px; border-bottom: 1px solid var(--borde); text-align: center; }
.vt-prog-tit {
  font-size: 10px; letter-spacing: 1.4px;
  color: var(--texto-tenue); margin-bottom: 6px;
}
.vt-prog-num {
  font-size: 30px; font-weight: 700; line-height: 1;
  color: var(--texto); font-variant-numeric: tabular-nums;
}
.vt-prog-num.completo { color: #f0c419; text-shadow: 0 0 14px rgba(240,196,25,.45); }
.vt-prog-barra {
  height: 6px; margin: 9px 0 6px;
  background: rgba(255,255,255,.08); border-radius: 3px; overflow: hidden;
}
.vt-prog-relleno {
  height: 100%; border-radius: 3px;
  background: linear-gradient(90deg, var(--acento), var(--acento-suave));
  transition: width .5s ease;
}
.vt-prog-det { font-size: 11px; color: var(--texto-tenue); }
.vt-prog-tipos {
  display: flex; justify-content: center; gap: 9px;
  margin-top: 6px; font-size: 11px; color: var(--texto-tenue);
  font-variant-numeric: tabular-nums;
}
.vt-prog-completo {
  margin-top: 8px; font-size: 11px; font-weight: 700;
  letter-spacing: .6px; color: #f0c419;
}

/* --- Lista de chicas --- */
.vt-chicas { flex: 1; overflow-y: auto; padding: 6px; display: flex; flex-direction: column; gap: 2px; }
.vt-chica {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; width: 100%; padding: 8px 10px;
  background: none; border: none; border-radius: 6px;
  color: var(--texto); font-size: 13px; text-align: left;
}
.vt-chica:hover  { background: rgba(255,255,255,.06); }
.vt-chica.activa { background: rgba(255,255,255,.10); }
.vt-chica-cnt {
  font-size: 11px; color: var(--texto-tenue);
  font-variant-numeric: tabular-nums;
}
.vt-chica.completa .vt-chica-cnt { color: #57c96f; font-weight: 600; }

/* --- Zona principal --- */
.vt-main { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.vt-cab { padding: 12px 16px; border-bottom: 1px solid var(--borde); }
.vt-cab-tit { font-size: 16px; font-weight: 600; }
.vt-cab-sub {
  font-size: 11px; color: var(--texto-tenue); margin-top: 3px;
  font-variant-numeric: tabular-nums;
}

.vt-rejilla {
  flex: 1; overflow-y: auto; padding: 14px;
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
  align-content: start;
}

.vt-celda {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: 8px; overflow: hidden;
  border: 1px solid var(--borde);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 4px; padding: 8px;
  background: rgba(255,255,255,.03);
}
.vt-celda.abierta { cursor: pointer; }
.vt-celda.abierta:hover { border-color: var(--acento-suave); }

/* Hueco por conseguir: se ve que falta, no se ve qué es */
.vt-celda.cerrada {
  background:
    repeating-linear-gradient(45deg,
      rgba(255,255,255,.02) 0 8px, transparent 8px 16px);
  border-style: dashed;
}
.vt-celda-ico   { font-size: 22px; opacity: .5; }
.vt-celda-tipo  { font-size: 11px; color: var(--texto-tenue); }
.vt-celda-quien { font-size: 10px; color: var(--texto-tenue); opacity: .7; }

.vt-celda-img,
.vt-celda-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vt-celda-falta { font-size: 10px; color: var(--texto-tenue); word-break: break-all; text-align: center; }

.vt-celda-audio {
  background: rgba(255,255,255,.07); border: 1px solid var(--borde);
  color: var(--texto); border-radius: 6px;
  padding: 8px 10px; font-size: 12px; max-width: 100%;
}
.vt-celda-audio:hover { background: rgba(255,255,255,.13); }
.vt-celda-dur { font-size: 10px; color: var(--texto-tenue); }

.vt-celda-pie {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 4px 7px; font-size: 10px;
  color: #fff; background: linear-gradient(transparent, rgba(0,0,0,.82));
  pointer-events: none;
}
.vt-celda.cerrada .vt-celda-pie { display: none; }

.vt-vacio { padding: 24px; color: var(--texto-tenue); text-align: center; }

@media (max-width: 720px) {
  .vt-lateral { width: 150px; }
  .vt-rejilla { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); }
}

/* --- Epílogo de versión: el cierre de la demo (fuera de ficción) --- */
.final-version {
  margin-top: 18px;
  padding: 14px 16px;
  border: 1px solid var(--borde);
  border-radius: 8px;
  background: rgba(192, 57, 43, .08);
}
.final-version-tit {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1.2px;
  color: var(--acento-suave);
  margin-bottom: 8px;
}
.final-version-txt {
  margin: 0 0 10px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--texto);
}
.final-version-vault {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--texto);
  margin-bottom: 10px;
}
.final-version-ganchos {
  margin: 0 0 10px;
  padding-left: 18px;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--texto-tenue);
}
.final-version-cta {
  font-size: 12px;
  color: var(--acento-suave);
  font-weight: 600;
}
.final-version-btn {
  display: inline-block;
  margin-top: 12px;
  padding: 8px 16px;
  border-radius: 999px;
  background: #f96854;            /* el coral de Patreon: se reconoce */
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
}
.final-version-btn:hover { filter: brightness(1.1); }

/* El código de descuento de F95 (solo gratis): violeta, la voz del
   sistema, para que se lea como un aviso del juego y no como un
   anuncio pegado encima */
.final-version-codigo {
  margin-top: 12px;
  padding: 10px 12px;
  border: 1px dashed rgb(var(--rgb-violeta) / .6);
  border-radius: 8px;
  background: rgb(var(--rgb-violeta) / .08);
}
.final-version-codigo-txt {
  font-size: 12.5px;
  color: var(--texto);
  margin-bottom: 8px;
}
.final-version-codigo-fila {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.final-version-codigo-fila code {
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 2px;
  color: var(--acento-violeta);
  text-shadow: 0 0 10px rgb(var(--rgb-violeta) / .6);
  user-select: all;
}
.final-version-copiar {
  padding: 5px 12px;
  border: 1px solid var(--acento-violeta);
  border-radius: 999px;
  background: transparent;
  color: var(--acento-violeta);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.final-version-copiar:hover { background: rgb(var(--rgb-violeta) / .18); }
.final-version-codigo-hasta {
  margin-top: 6px;
  font-size: 11.5px;
  color: var(--texto-tenue);
}

/* ############################################################
   ############################################################
   CAPA DE TEMA — "MIDNIGHT CYBER-MELANCHOLY"
   ------------------------------------------------------------
   Va LA ÚLTIMA a propósito. Todo lo de arriba es la estructura
   (qué va dónde); esto es la personalidad (cómo se siente).
   Al ir después, gana a igualdad de especificidad sin tener que
   ensuciar las reglas originales con !important.

   Cada app tiene su color de neón, y ese color es su identidad:
     Wisp   → esmeralda   Kord   → blurple
     Velvet → carmesí     Glim   → magenta
     Vapor  → cyan        SO     → ámbar / violeta

   Ningún selector nuevo inventa clases: todos existen ya en el
   HTML que genera el JS. No se toca ningún #id ni ninguna .clase.
   ############################################################
   ############################################################ */

/* ============================================================
   T0. TIPOGRAFÍA TRANSVERSAL
   Outfit manda en la UI, Inter en lo que se lee, mono en el HUD.
   ============================================================ */
.ventana-titulo,
.opcion,
.aviso-tit,
.ayuda-nombre,
.tr-cab-tit, .tr-item-nom,
.gu-cab, .gu-slot-nom,
.co-cabecera, .co-asunto,
.vt-cab-tit, .pl-titulo, .wp-nom,
.app-final h2 {
  font-family: var(--fuente-ui);
}

.burbuja, .dc-msg-texto, .final-texto,
.co-parrafo, .gl-pie-txt, .ayuda-bloque-txt,
.tr-item-desc, .vp-titem-desc {
  font-family: var(--fuente-texto);
}

/* HUD: todo lo que sea una cifra que se lee de reojo */
.opcion-coste, .ayuda-coste-puntos,
.vt-prog-num, .vt-prog-det, .vt-prog-tipos, .vt-chica-cnt,
.vp-cartera, .vp-lp, .vp-mcard-lp, .vp-mcard-stats b,
.hab-cred-num, .media-slot-id, .lightbox-falta,
.gu-slot-fecha, .final-version-vault {
  font-family: var(--fuente-mono);
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   T1. OPCIONES DE MATT (compartidas por todas las apps)
   Es el botón que más se pulsa del juego. Merece peso.
   ============================================================ */
.opciones {
  background: linear-gradient(180deg, rgba(255,255,255,.02), transparent), var(--panel);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.opcion {
  border-radius: 10px;
  font-weight: 500;
  transition:
    border-color .16s ease,
    background .16s ease,
    box-shadow .22s ease,
    transform .14s cubic-bezier(.2,.8,.2,1);
}
.opcion:hover:not(.bloqueada) {
  transform: translateX(2px);
  border-color: var(--acento-carmesi);
  background: rgb(var(--rgb-carmesi) / .10);
  box-shadow: 0 0 18px rgb(var(--rgb-carmesi) / .18), inset 0 1px 0 rgba(255,255,255,.06);
}
.opcion-coste {
  letter-spacing: 1.5px;
  text-shadow: 0 0 8px rgb(var(--rgb-carmesi) / .5);
}

/* --- SEÑAL DE RAMA CALIENTE ---
   Punto rojo en el filo de una opcion que abre una escena +18.
   Deliberadamente pequeño: tiene que verse de reojo y que el
   jugador lo INTUYA, no leerse como una etiqueta que le diga
   "aqui esta el contenido". Si canta demasiado, deja de ser una
   decision y se convierte en el boton obvio.
   Se pone desde content/ con `caliente: true` en la opcion. */
.opcion-caliente { position: relative; }
.opcion-punto {
  position: absolute;
  top: 50%;
  right: 9px;
  width: 6px;
  height: 6px;
  margin-top: -3px;
  border-radius: 50%;
  background: var(--acento-carmesi);
  box-shadow: 0 0 6px rgb(var(--rgb-carmesi) / .8);
  opacity: .75;
  pointer-events: none;
  animation: opcionLatido 3.4s ease-in-out infinite;
}
@keyframes opcionLatido {
  0%, 100% { opacity: .5;  box-shadow: 0 0 4px rgb(var(--rgb-carmesi) / .5); }
  50%      { opacity: .95; box-shadow: 0 0 10px rgb(var(--rgb-carmesi) / .9); }
}
/* Al pasar por encima si se enciende del todo: ya has ido tu a el */
.opcion-caliente:hover:not(.bloqueada) .opcion-punto {
  opacity: 1;
  box-shadow: 0 0 12px rgb(var(--rgb-carmesi) / 1);
  animation: none;
}
/* Deja sitio al punto para que no se pise con el texto */
.opcion-caliente .opcion-txt { padding-right: 12px; }

/* Si la opcion ademas cuesta atencion, el punto se aparta para
   no montarse encima de los circulitos del coste. */
.opcion-caliente:has(.opcion-coste) .opcion-punto { right: auto; left: 9px; }
.opcion-caliente:has(.opcion-coste) .opcion-txt { padding-right: 0; padding-left: 12px; }
.opcion.bloqueada { opacity: .35; }

/* ============================================================
   T2. WISP — intimidad en verde esmeralda
   ============================================================ */
.app-wisp { --wa-verde: var(--acento-esmeralda); }

.wisp-yo-nom, .wisp-nombre, .wisp-c-nom, .wisp-bv-t {
  font-family: var(--fuente-ui);
}
.wisp-cabecera, .wisp-yo {
  background: linear-gradient(180deg, rgba(255,255,255,.035), transparent), var(--wa-barra);
}
.wisp-contacto.activo {
  box-shadow: inset 2px 0 0 var(--acento-esmeralda);
}
/* Badge de mensajes sin leer: cápsula de neón verde */
.wisp-c-badge, .wisp-estados-punto {
  background: linear-gradient(135deg, #34d399, var(--acento-esmeralda));
  color: #04231a;
  font-family: var(--fuente-mono);
  font-weight: 600;
  box-shadow: 0 0 12px rgb(var(--rgb-esmeralda) / .65);
}
.estilo-wisp .burbuja.mia {
  background: linear-gradient(150deg, #0b6b56, #064e3b);
  color: #eafaf4;
}
.app-wisp .opcion:hover:not(.bloqueada) {
  border-color: var(--acento-esmeralda);
  background: rgb(var(--rgb-esmeralda) / .12);
  box-shadow: 0 0 18px rgb(var(--rgb-esmeralda) / .22), inset 0 1px 0 rgba(255,255,255,.06);
}
.app-wisp .opcion-coste { color: #6ee7b7; text-shadow: 0 0 8px rgb(var(--rgb-esmeralda) / .5); }

/* Anillo de Estados 24h: verde girando mientras esté sin ver */
.wisp-pe-aro { position: relative; background: none !important; }
.wisp-pe-aro::before {
  content: '';
  position: absolute; inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 0deg, var(--acento-esmeralda), #6ee7b7, #22d3ee, var(--acento-esmeralda));
  animation: aroGira 4s linear infinite;
}
.wisp-pe-aro > * { position: relative; }
.wisp-pe-item.visto .wisp-pe-aro::before {
  background: rgba(134,150,160,.32);
  animation: none;
}
@keyframes aroGira { to { transform: rotate(360deg); } }

/* ============================================================
   T3. KORD — red social gamer en blurple
   ============================================================ */
.kord-serv-nom, .kord-chat-cab-nom, .dc-msg-nom, .kord-yo-nom {
  font-family: var(--fuente-ui);
}
.kord-serv, .kord-serv-mas {
  transition: border-radius .15s ease, box-shadow .22s ease, transform .15s ease;
}
.kord-serv:hover, .kord-serv-mas:hover {
  transform: translateY(-1px);
  box-shadow: 0 0 18px rgb(var(--rgb-blurple) / .55);
}
/* Canal activo: barra LED blurple en el filo izquierdo */
.kord-canal.activo {
  box-shadow: inset 2px 0 0 var(--acento-blurple), 0 0 14px rgb(var(--rgb-blurple) / .14);
}
.kord-canal-coste {
  font-family: var(--fuente-mono);
  color: var(--acento-ambar);
  text-shadow: 0 0 8px rgb(var(--rgb-ambar) / .45);
}
.kord-miembro { transition: background .14s ease; }
.app-kord .opcion:hover:not(.bloqueada) {
  border-color: var(--acento-blurple);
  background: rgb(var(--rgb-blurple) / .14);
  box-shadow: 0 0 18px rgb(var(--rgb-blurple) / .26), inset 0 1px 0 rgba(255,255,255,.06);
}
.app-kord .opcion-coste { color: #a5b4fc; text-shadow: 0 0 8px rgb(var(--rgb-blurple) / .5); }

/* ============================================================
   T4. GLIM — stories y feed en magenta
   ============================================================ */
.gl-post-nom, .gl-dm-nom, .gl-pf-user, .gl-dm-cab, .gl-chat-nom {
  font-family: var(--fuente-ui);
}
/* Anillo de historia: degradado neón girando */
.gl-hist-aro { position: relative; background: none !important; }
.gl-hist-aro::before {
  content: '';
  position: absolute; inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 0deg,
    var(--acento-ambar), #ff5f6d, var(--acento-magenta), #a855f7, var(--acento-ambar));
  animation: aroGira 5s linear infinite;
  filter: saturate(1.15);
}
.gl-hist-aro > * { position: relative; }
.gl-hist:hover .gl-hist-aro::before { animation-duration: 1.6s; }
.gl-hist.vista .gl-hist-aro::before { background: #363636; animation: none; filter: none; }

.gl-badge {
  background: linear-gradient(135deg, var(--acento-magenta), #ff3d71);
  font-family: var(--fuente-mono);
  font-weight: 600;
  box-shadow: 0 0 12px rgb(var(--rgb-magenta) / .6);
}
.gl-like.liked {
  color: var(--acento-carmesi);
  filter: drop-shadow(0 0 8px rgb(var(--rgb-carmesi) / .75));
}
.gl-dm-item.activo { box-shadow: inset 2px 0 0 var(--acento-magenta); }
.gl-dm-foto {
  background: linear-gradient(135deg, var(--acento-magenta), var(--acento-carmesi));
  box-shadow: 0 0 12px rgb(var(--rgb-magenta) / .5);
}
.app-glim .opcion:hover:not(.bloqueada) {
  border-color: var(--acento-magenta);
  background: rgb(var(--rgb-magenta) / .13);
  box-shadow: 0 0 18px rgb(var(--rgb-magenta) / .26), inset 0 1px 0 rgba(255,255,255,.06);
}
.app-glim .opcion-coste { color: #f0abfc; text-shadow: 0 0 8px rgb(var(--rgb-magenta) / .5); }

/* ============================================================
   T5. VAPOR — biblioteca y e-sports en cyan
   ============================================================ */
.app-vapor { --vp-azul: var(--acento-cyan); }

.vp-logo {
  font-family: var(--fuente-ui);
  font-weight: 700;
  color: var(--acento-cyan);
  text-shadow: 0 0 18px rgb(var(--rgb-cyan) / .55);
}
.vp-tab, .vp-lib-nom, .vp-titem-nom, .vp-noticia-tit, .vp-stream-tit {
  font-family: var(--fuente-ui);
}
.vp-tab.activo {
  background: rgb(var(--rgb-cyan) / .14);
  box-shadow: inset 0 0 0 1px rgb(var(--rgb-cyan) / .35), 0 0 16px rgb(var(--rgb-cyan) / .18);
}
.vp-cartera {
  font-family: var(--fuente-mono);
  color: #34d399;
  padding: 5px 11px;
  border-radius: var(--radio-capsula);
  background: rgb(var(--rgb-esmeralda) / .08);
  border: 1px solid rgb(var(--rgb-esmeralda) / .22);
}

/* BADGE CHALLENGER: metal pulido con luz cyan. Es el trofeo que
   define a Matt fuera del chat; tiene que verse caro. */
.vp-rango-badge {
  color: #04222a;
  background:
    linear-gradient(135deg, #e6fdff 0%, #67e8f9 30%, var(--acento-cyan) 55%, #0e7490 78%, #a5f3fc 100%);
  box-shadow:
    0 0 22px rgb(var(--rgb-cyan) / .6),
    inset 0 1px 0 rgba(255,255,255,.7),
    inset 0 -2px 6px rgba(0,0,0,.35);
  animation: vpBrillo 2.4s ease-in-out infinite alternate;
}
@keyframes vpBrillo {
  from { box-shadow: 0 0 14px rgb(var(--rgb-cyan) / .42), inset 0 1px 0 rgba(255,255,255,.7), inset 0 -2px 6px rgba(0,0,0,.35); }
  to   { box-shadow: 0 0 32px rgb(var(--rgb-cyan) / .85), inset 0 1px 0 rgba(255,255,255,.7), inset 0 -2px 6px rgba(0,0,0,.35); }
}
.vp-rango-fila b {
  font-family: var(--fuente-ui);
  font-weight: 700;
  /* El último tramo no baja de #22d3ee: con el cyan puro la cola de
     la palabra se apagaba contra el panel y no se leía "CHALLENGER". */
  background: linear-gradient(120deg, #fff 5%, #a5f3fc 50%, #22d3ee 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  color: #67e8f9;
  text-shadow: none;
}
.vp-lp-fill { background: linear-gradient(90deg, var(--acento-cyan), #a5f3fc); }
.vp-srv-punto { box-shadow: 0 0 10px var(--vp-win); }

.vp-play {
  font-family: var(--fuente-ui);
  background: linear-gradient(135deg, #22d3ee, #0e7490);
  box-shadow: 0 10px 30px rgb(var(--rgb-cyan) / .30);
}
.vp-play:hover:not(:disabled) { box-shadow: 0 12px 38px rgb(var(--rgb-cyan) / .48); }
.vp-titem-btn { background: linear-gradient(135deg, #22d3ee, #0e7490); }
.vp-lib-juego.principal { box-shadow: inset 0 0 0 1px rgb(var(--rgb-cyan) / .28), 0 0 20px rgb(var(--rgb-cyan) / .10); }
/* Badge LIVE del stream, mismo idioma que el de la webcam de Kord */
.vp-live {
  border-radius: var(--radio-capsula);
  font-family: var(--fuente-mono);
  font-weight: 600;
  letter-spacing: 1.2px;
  background: linear-gradient(135deg, var(--acento-carmesi), #ff4d6d);
  box-shadow: 0 0 16px rgb(var(--rgb-carmesi) / .7);
  animation: webcam-parpadeo 1.8s steps(1) infinite;
}
.vp-espectadores { font-family: var(--fuente-mono); backdrop-filter: blur(6px); }
.dc-estado.partida { box-shadow: 0 0 8px rgb(var(--rgb-cyan) / .85); }

/* ============================================================
   T6. VELVET — erotismo +18 en carmesí y oro
   Cristal granate nocturno: la boutique es cara y lo enseña.
   ============================================================ */
.app-velvet {
  --vv-magenta: var(--acento-carmesi);
  --vv-red:     #a8123c;
  --vv-gold:    #f0c274;
  --vv-rosa:    #f3a48b;
  --vv-brd-glow: rgba(240,194,116,.45);
  font-family: var(--fuente-texto);
  background:
    radial-gradient(1100px 460px at 12% -12%, rgb(var(--rgb-carmesi) / .20), transparent 60%),
    radial-gradient(820px 460px at 104% -6%, rgba(240,194,116,.10), transparent 55%),
    radial-gradient(760px 620px at 88% 118%, rgba(168,18,60,.16), transparent 60%),
    linear-gradient(158deg, #130d14, #0a070c);
}
/* Tarjeta de producto: cristal granate, no gris */
.app-velvet .vv-prod {
  background: linear-gradient(160deg, rgba(58,20,34,.42), rgba(18,10,18,.55));
  border-radius: 14px;
}
.app-velvet .vv-prod:hover {
  box-shadow: 0 22px 48px rgba(0,0,0,.6), 0 0 28px rgb(var(--rgb-carmesi) / .28);
}
.app-velvet .vv-prod-nom { font-family: var(--fuente-ui); font-weight: 600; }
/* Precio en oro, en Outfit: la cifra es parte del lujo */
.app-velvet .vv-prod-precio,
.app-velvet .vv-banner-precio,
.app-velvet .vv-envio-hero-precio {
  font-family: var(--fuente-ui);
  font-weight: 700;
  letter-spacing: .3px;
  background: linear-gradient(120deg, #fff5e1 5%, var(--vv-gold) 55%, #c9962e 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--vv-gold);
}
/* Botón de compra: resplandor sensual al acercarse */
.app-velvet .vv-prod-btn {
  font-family: var(--fuente-ui);
  transition: background .2s ease, box-shadow .28s ease, transform .16s cubic-bezier(.2,.8,.2,1);
}
.app-velvet .vv-prod-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 26px rgb(var(--rgb-carmesi) / .5), 0 0 22px rgba(240,194,116,.28);
}
.app-velvet .vv-tab, .app-velvet .vv-cat { font-family: var(--fuente-ui); }
.app-velvet .vv-dinero { font-family: var(--fuente-mono); }
.app-velvet .vv-vip-chip { font-family: var(--fuente-mono); }

/* ============================================================
   T7. VAULT — la bóveda privada
   Miniatura velada que se revela con un barrido de luz. La
   colección es la meta del juego: enseñarla tiene que premiar.
   ============================================================ */
.app-vault {
  background:
    radial-gradient(900px 500px at 85% -10%, rgb(var(--rgb-carmesi) / .10), transparent 60%),
    linear-gradient(160deg, #100a11, #07080d);
}
.vt-lateral { background: rgba(0,0,0,.30); }

/* HUD de colección global */
.vt-prog-tit { font-family: var(--fuente-mono); text-transform: uppercase; }
.vt-prog-num {
  font-family: var(--fuente-mono);
  color: var(--acento-carmesi-suave);
  text-shadow: 0 0 18px rgb(var(--rgb-carmesi) / .45);
}
.vt-prog-num.completo {
  color: var(--vv-gold, #f0c274);
  text-shadow: 0 0 22px rgba(240,194,116,.6);
}
.vt-prog-barra {
  border: 1px solid var(--borde);
  background: rgba(0,0,0,.45);
}
.vt-prog-relleno {
  background: linear-gradient(90deg, var(--acento-carmesi), #ff8fa3);
  box-shadow: 0 0 12px rgb(var(--rgb-carmesi) / .6);
}
.vt-prog-completo {
  font-family: var(--fuente-mono);
  color: #f0c274;
  text-shadow: 0 0 14px rgba(240,194,116,.5);
}

/* Contador por chica: cápsula HUD. De un vistazo ves a quién
   te falta por completar. */
.vt-chica { font-family: var(--fuente-ui); transition: background .15s ease, box-shadow .22s ease; }
.vt-chica-cnt {
  font-family: var(--fuente-mono);
  font-size: 10.5px;
  padding: 2px 7px;
  border-radius: var(--radio-capsula);
  background: rgba(255,255,255,.05);
  border: 1px solid var(--borde);
}
.vt-chica.activa { box-shadow: inset 2px 0 0 var(--acento-carmesi); }
.vt-chica.completa .vt-chica-cnt {
  color: #ffe6b8;
  background: rgba(240,194,116,.12);
  border-color: rgba(240,194,116,.45);
  box-shadow: 0 0 12px rgba(240,194,116,.30);
}

/* ARREGLO DE MAQUETACIÓN (venía de antes del rediseño):
   las filas de la rejilla se quedaban en 18px de alto. Chromium no
   cuenta el alto que .vt-celda saca de su aspect-ratio al medir una
   fila `auto`, así que las celdas se salían de su fila y se pisaban
   unas a otras: la colección se veía como tres franjas rayadas.
   Con max-content la fila mide lo que mide la celda (3/4) y la
   rejilla vuelve a ser una rejilla. */
.vt-rejilla { grid-auto-rows: max-content; }

/* Celda desbloqueada: velada hasta que pasas el ratón */
.vt-celda {
  border-radius: 10px;
  transition: transform .22s cubic-bezier(.2,.8,.2,1), box-shadow .26s ease, border-color .2s ease;
}
.vt-celda-img, .vt-celda-video {
  filter: blur(5px) brightness(.62) saturate(.85);
  transform: scale(1.06);
  transition: filter .38s ease, transform .38s ease;
}
.vt-celda.abierta:hover {
  transform: translateY(-3px);
  border-color: var(--acento-carmesi);
  box-shadow: 0 16px 34px rgba(0,0,0,.6), 0 0 26px rgb(var(--rgb-carmesi) / .35);
}
.vt-celda.abierta:hover .vt-celda-img,
.vt-celda.abierta:hover .vt-celda-video {
  filter: none;
  transform: scale(1);
}
/* Barrido de luz al revelar */
.vt-celda.abierta::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(115deg, transparent 35%, rgba(255,255,255,.22) 50%, transparent 65%);
  opacity: 0;
  transform: translateX(-110%);
  pointer-events: none;
}
.vt-celda.abierta:hover::after { animation: vaultRevela .65s ease-out; }
@keyframes vaultRevela {
  0%   { opacity: 0;  transform: translateX(-110%); }
  40%  { opacity: 1; }
  100% { opacity: 0;  transform: translateX(110%); }
}

/* Hueco por conseguir: chapa de bóveda cerrada.
   El borde SÍ tiene que verse: si no, las celdas vacías se funden
   en una sola mancha rayada y no se cuenta lo que falta. */
.vt-celda.cerrada {
  border: 1px dashed rgba(255,255,255,.16);
  background:
    repeating-linear-gradient(45deg,
      rgba(255,255,255,.028) 0 9px, transparent 9px 18px),
    rgba(0,0,0,.20);
}
.vt-celda.cerrada .vt-celda-ico {
  opacity: .55;
  filter: drop-shadow(0 0 10px rgb(var(--rgb-carmesi) / .4));
}
.vt-celda-tipo {
  font-family: var(--fuente-mono);
  font-size: 10px;
  letter-spacing: .5px;
  color: var(--texto-tenue);
}
.vt-celda-quien { opacity: .85; }
.vt-celda-pie { font-family: var(--fuente-ui); }

/* ============================================================
   T8. HABITAT, CORREO, TROFEOS, GUARDADO
   Apps utilitarias: solo se les ajusta la tipografía y el filo
   de luz para que no desentonen con el resto del sistema.
   ============================================================ */
.hab-sala-nom, .hab-amigo-nom, .hab-salas-tit { font-family: var(--fuente-ui); }
.hab-cred-num { text-shadow: 0 0 14px rgba(127,214,255,.45); }
.hab-presente { backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }

.app-correo .co-item.activo { box-shadow: inset 3px 0 0 var(--acento-carmesi); }
.app-correo .co-item.nuevo .co-item-de::before {
  text-shadow: 0 0 10px rgb(var(--rgb-carmesi) / .8);
}
.app-correo .co-accion {
  font-family: var(--fuente-ui);
  background: linear-gradient(135deg, var(--acento-carmesi), #b81f6a);
  box-shadow: 0 6px 18px rgb(var(--rgb-carmesi) / .25);
}

.logro-toast {
  background: linear-gradient(150deg, rgba(42,33,64,.96), rgba(13,16,25,.96));
  backdrop-filter: var(--blur-cristal);
  -webkit-backdrop-filter: var(--blur-cristal);
  border-color: rgba(240,194,116,.55);
}
.logro-toast-cab { font-family: var(--fuente-mono); }
.logro-toast-tit { font-family: var(--fuente-ui); }
.tr-barra-relleno { box-shadow: 0 0 12px rgba(240,194,116,.5); }
.tr-item.hecho { box-shadow: 0 0 18px rgba(240,194,116,.10); }

.gu-btn { font-family: var(--fuente-ui); }
.gu-btn-guardar { background: linear-gradient(135deg, var(--acento-carmesi), #b81f6a); }
.gu-btn-cargar  { background: linear-gradient(135deg, var(--acento-violeta), #4c2a9e); }
.gu-slot.auto   { border-color: rgb(var(--rgb-violeta) / .4); box-shadow: 0 0 16px rgb(var(--rgb-violeta) / .10); }

/* ============================================================
   T9. SLOTS DE MEDIA VACÍOS
   Mientras Marc no ponga el archivo, el hueco se ve como un
   panel de diagnóstico del sistema, no como un error.
   ============================================================ */
.media-slot, .foto-falta {
  border-color: rgba(255,255,255,.10);
  background:
    repeating-linear-gradient(45deg,
      rgba(255,255,255,.018) 0 9px, transparent 9px 18px),
    rgba(0,0,0,.32);
  border-radius: 12px;
}
.media-slot-id {
  font-family: var(--fuente-mono);
  font-weight: 600;
  color: var(--acento-ambar);
  text-shadow: 0 0 12px rgb(var(--rgb-ambar) / .35);
}
.media-slot-video, .media-slot-webcam { border-color: rgb(var(--rgb-carmesi) / .35); }
.media-slot-video .media-slot-id, .media-slot-webcam .media-slot-id {
  color: var(--acento-carmesi-suave);
  text-shadow: 0 0 12px rgb(var(--rgb-carmesi) / .45);
}

/* ============================================================
   T10. ESCENA A PANTALLA COMPLETA
   El momento más íntimo del juego: el marco desaparece y solo
   quedan las marcas de intensidad.
   ============================================================ */
.escena-overlay {
  background: radial-gradient(circle at 50% 45%, #0b0710 0%, #04050a 100%);
}
.escena-titulo { font-family: var(--fuente-ui); font-weight: 600; }
.escena-fase   { font-family: var(--fuente-mono); }
.escena-marca.activa {
  background: var(--acento-carmesi-suave);
  box-shadow: 0 0 14px rgb(var(--rgb-carmesi) / .85);
}
.escena-mas {
  font-family: var(--fuente-ui);
  font-weight: 600;
  border-radius: var(--radio-capsula);
  background: linear-gradient(135deg, var(--acento-carmesi), #b81f6a);
  box-shadow: 0 8px 24px rgb(var(--rgb-carmesi) / .30);
  transition: transform .16s cubic-bezier(.2,.8,.2,1), box-shadow .25s ease, filter .18s ease;
}
.escena-mas:hover:not(:disabled) {
  background: linear-gradient(135deg, var(--acento-carmesi), #b81f6a);
  filter: brightness(1.08);
  box-shadow: 0 12px 32px rgb(var(--rgb-carmesi) / .48);
}

/* ============================================================
   T11. AYUDA [?] Y TUTORIAL
   ============================================================ */
.ayuda-card {
  background: linear-gradient(160deg, rgba(24,30,46,.96), rgba(11,14,22,.97));
  backdrop-filter: var(--blur-acrilico);
  -webkit-backdrop-filter: var(--blur-acrilico);
  border-color: var(--borde-fuerte);
}
.ayuda-bloque-tit { font-family: var(--fuente-mono); }
.ayuda-ico { box-shadow: inset 0 1px 0 rgba(255,255,255,.08); }

/* El tutorial vive entero en su propia sección («TUTORIAL — guía del
   Día 1», más arriba). No repetir aquí sus reglas: esta capa va
   después y las pisaría por orden. */

/* ============================================================
   CRÉDITOS
   ------------------------------------------------------------
   Se lee de arriba abajo y en silencio, así que manda el espacio
   y no el adorno: una columna estrecha, cada apartado separado
   por aire en vez de por cajas, y la línea de neón del sistema
   marcando el título.

   El nombre pesa y el papel no. Por eso el papel va en --texto-tenue
   y a la derecha: se ve quién ha hecho el juego de un vistazo,
   y el detalle solo si se busca.
   ============================================================ */
.app-creditos {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  background: var(--fondo-2);
}

.cr-cab {
  padding: 26px 28px 20px;
  border-bottom: 1px solid var(--borde);
  flex: none;
}
.cr-titulo {
  font-family: var(--fuente-ui);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--texto);
}
.cr-intro {
  margin-top: 5px;
  font-size: 12px;
  color: var(--texto-tenue);
  font-style: italic;
}

.cr-zona {
  flex: 1;
  overflow-y: auto;
  padding: 22px 28px 8px;
}

.cr-bloque { margin-bottom: 26px; }
.cr-bloque:last-child { margin-bottom: 10px; }

.cr-bloque-tit {
  margin: 0 0 3px;
  font-family: var(--fuente-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .19em;
  text-transform: uppercase;
  color: var(--neon);
}
.cr-bloque-nota {
  margin: 0 0 11px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--texto-tenue);
}

/* Cada línea: nombre a la izquierda, papel a la derecha, y una
   guía de puntos entre medias — como en los créditos de un libro.
   El `flex: 1` del separador es lo que empuja el papel al margen
   sin tener que fijar anchos. */
.cr-linea {
  display: flex;
  flex-wrap: wrap;          /* sin esto el enlace no baja de línea:
                               se queda estrujando al papel y parte
                               «Iconos de la / interfaz» */
  align-items: baseline;
  gap: 2px 9px;
  padding: 5px 0;
  font-size: 13px;
  line-height: 1.4;
}
.cr-quien {
  color: var(--texto);
  font-weight: 500;
}
.cr-papel {
  margin-left: auto;
  font-size: 11px;
  color: var(--texto-tenue);
  text-align: right;
  white-space: nowrap;      /* el papel es corto: antes se parte la
                               línea entera que una etiqueta de dos
                               palabras */
}
.cr-enlace {
  flex-basis: 100%;
  margin-top: -2px;
  font-family: var(--fuente-mono);
  font-size: 10px;
  color: var(--acento-violeta);
  letter-spacing: .02em;
}

.cr-vacio {
  color: var(--texto-tenue);
  font-size: 12px;
  font-style: italic;
  text-align: center;
  padding: 40px 0;
}

.cr-pie {
  flex: none;
  padding: 13px 28px 16px;
  border-top: 1px solid var(--borde);
  font-size: 10px;
  line-height: 1.5;
  color: var(--texto-tenue);
  background: rgba(0, 0, 0, .18);
}


/* ============================================================
   GLIM — TODOS LOS POSTS DEL FEED MIDEN LO MISMO
   ------------------------------------------------------------
   La imagen del post solo tenía `width: 100%`, sin altura, así que
   cada post medía lo que midiera su foto: uno apaisado bajito, el
   siguiente vertical larguísimo. Y el hueco de «falta imagen» tenía
   su propia altura fija de 260px, que tampoco coincidía con nada.
   Instagram no hace eso: encaja todas en el mismo marco.

   4:5 es el formato vertical de Instagram. Se elige ese y no el
   cuadrado porque casi todo el material son personas en vertical:
   con 4:5 una foto vertical pierde poco por arriba y por abajo, y
   con 1:1 perdería un tercio y cortaría cabezas.

   `object-fit: cover` recorta, NO deforma. Y el recorte es solo del
   feed: al pulsar la foto el visor la abre ENTERA.

   Va limitado a `.gl-post-marco >` a propósito: `.gl-slot` se usa
   también en el visor de historias (9:16) y en la cuadrícula del
   perfil (1:1), que tienen sus propias reglas y no se tocan.

   De regalo, el feed deja de dar saltos mientras cargan las fotos:
   el marco ya tiene su altura antes de que llegue la imagen.

   SI UN RECORTE CORTA ALGO IMPORTANTE, no se toca el archivo: se
   añade `encuadre: 'top'` (o 'bottom', o '50% 30%') al post en
   content/glim.js, igual que en Instagram eliges el recorte.

   Y SI NO ADMITE RECORTE —una infografía, una captura con texto de
   lado a lado—, `encuadre: 'entera'`: la imagen completa dentro del
   mismo marco, con franjas oscuras. El post sigue midiendo igual.
   ============================================================ */
.gl-post-marco > .gl-slot {
  aspect-ratio: 4 / 5;
  overflow: hidden;
}
.gl-post-marco > .gl-slot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
.gl-post-marco > .gl-slot .media-slot {
  height: 100%;
  min-height: 0;
  box-sizing: border-box;
}

/* ============================================================
   MARGIN — la cartera de Matt (src/apps/margin.js)
   ------------------------------------------------------------
   Un terminal de bolsa en la misma ceniza del sistema: el color
   de la app vive solo en el icono, como en las demás. Aquí el
   único color con significado es el del mercado: esmeralda si
   sube, carmesí si baja. Cifras siempre en mono, para que los
   dígitos queden en columna y no bailen al cambiar.
   ============================================================ */
.app-margin {
  display: flex; flex-direction: column;
  width: 100%;
  background: var(--fondo);
  color: var(--texto);
  font-family: var(--fuente-texto);
  --mg-sube: var(--acento-esmeralda);
  --mg-baja: var(--acento-carmesi-suave);
  --mg-rgb-sube: var(--rgb-esmeralda);
  --mg-rgb-baja: var(--rgb-carmesi);
}
.mg-nav {
  display: flex; align-items: center; gap: 18px;
  padding: 10px 18px;
  border-bottom: 1px solid var(--borde);
  background: var(--panel-solido);
}
.mg-logo { font-family: var(--fuente-ui); font-weight: 800; font-size: 17px; letter-spacing: .02em; }
.mg-tabs { display: flex; gap: 4px; }
.mg-tab {
  font-family: var(--fuente-ui); font-size: 13px; font-weight: 600;
  color: var(--texto-tenue); background: none; border: 0;
  padding: 6px 12px; border-radius: 8px; cursor: pointer;
}
.mg-tab:hover { color: var(--texto); background: var(--panel-alto-solido); }
.mg-tab.activo { color: var(--texto); background: var(--panel-alto-solido); box-shadow: inset 0 -2px 0 var(--texto); }
.mg-estado {
  margin-left: auto; display: flex; align-items: center; gap: 7px;
  font-family: var(--fuente-mono); font-size: 11.5px; color: var(--texto-tenue);
}
.mg-vivo {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--mg-sube);
  animation: mg-latido 2s ease-out infinite;
}
@keyframes mg-latido {
  0%   { box-shadow: 0 0 0 0 rgb(var(--mg-rgb-sube) / .6); }
  70%  { box-shadow: 0 0 0 7px rgb(var(--mg-rgb-sube) / 0); }
  100% { box-shadow: 0 0 0 0 rgb(var(--mg-rgb-sube) / 0); }
}

.mg-cuerpo {
  flex: 1; min-height: 0; overflow-y: auto;
  display: grid; gap: 14px; padding: 16px 18px 22px;
  align-content: start;
}
.mg-cartera { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); }
.mg-cartera .mg-patrimonio { grid-row: span 2; }
.mg-mercado { grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); }
@media (max-width: 760px) {
  .mg-cartera, .mg-mercado { grid-template-columns: minmax(0, 1fr); }
  .mg-cartera .mg-patrimonio { grid-row: auto; }
}

.mg-panel {
  background: var(--panel-solido);
  border: 1px solid var(--borde);
  border-radius: 12px;
  padding: 14px 16px;
  min-width: 0;
}
.mg-etq {
  font-family: var(--fuente-ui); font-size: 11px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase;
  color: var(--texto-tenue); margin-bottom: 8px;
}
.mg-etq:not(:first-child) { margin-top: 14px; }
.mg-total {
  font-family: var(--fuente-mono); font-weight: 600;
  font-size: 30px; letter-spacing: -.01em; line-height: 1.1;
}
.mg-total-cambio { display: flex; align-items: center; gap: 10px; margin: 6px 0 10px; }
.mg-ganado { font-family: var(--fuente-mono); font-size: 12.5px; }

.mg-chip {
  display: inline-block; white-space: nowrap;
  font-family: var(--fuente-mono); font-size: 11.5px; font-weight: 600;
  padding: 2px 7px; border-radius: 6px;
}
.mg-chip.sube { color: var(--mg-sube); background: rgb(var(--mg-rgb-sube) / .13); }
.mg-chip.baja { color: var(--mg-baja); background: rgb(var(--mg-rgb-baja) / .14); }
.mg-ganado.sube, .mg-mov-imp.sube { color: var(--mg-sube); }
.mg-ganado.baja, .mg-mov-imp.baja { color: var(--mg-baja); }

/* --- La gráfica --- */
.mg-grafica-caja { position: relative; }
.mg-grafica { display: block; width: 100%; height: 200px; overflow: visible; }
.mg-patrimonio .mg-grafica { height: 230px; }
.mg-detalle .mg-grafica { height: 250px; }
.mg-linea { fill: none; stroke-width: 2; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.mg-ref { stroke: var(--borde-fuerte); stroke-width: 1; stroke-dasharray: 3 4; vector-effect: non-scaling-stroke; }
.mg-grafica.sube .mg-linea { stroke: var(--mg-sube); }
.mg-grafica.baja .mg-linea { stroke: var(--mg-baja); }
.mg-grafica.sube .mg-deg-a { stop-color: rgb(var(--mg-rgb-sube)); stop-opacity: .28; }
.mg-grafica.baja .mg-deg-a { stop-color: rgb(var(--mg-rgb-baja)); stop-opacity: .26; }
.mg-deg-b { stop-color: var(--fondo); stop-opacity: 0; }
.mg-punto {
  position: absolute; width: 8px; height: 8px; margin: -4px 0 0 -4px;
  border-radius: 50%; pointer-events: none;
}
.mg-punto.sube { background: var(--mg-sube); box-shadow: 0 0 0 4px rgb(var(--mg-rgb-sube) / .2); }
.mg-punto.baja { background: var(--mg-baja); box-shadow: 0 0 0 4px rgb(var(--mg-rgb-baja) / .2); }

.mg-rangos { display: flex; gap: 4px; margin-top: 10px; }
.mg-rango {
  flex: 1; font-family: var(--fuente-mono); font-size: 11.5px; font-weight: 600;
  color: var(--texto-tenue); background: none;
  border: 1px solid transparent; border-radius: 7px; padding: 5px 0; cursor: pointer;
}
.mg-rango:hover { color: var(--texto); }
.mg-rango.activo { color: var(--texto); background: var(--panel-alto-solido); border-color: var(--borde-fuerte); }

/* --- Reparto y tabla de posiciones --- */
.mg-barra-reparto {
  display: flex; gap: 2px; height: 8px; border-radius: 4px; overflow: hidden;
  margin-bottom: 10px;
}
.mg-tramo { min-width: 2px; }
/* Seis grises cálidos escalonados en vez de seis colores: el color
   ya significa «sube / baja» en esta app y no puede significar
   también «qué activo es». */
.app-margin .t0 { background: #e9dfe6; } .app-margin .t1 { background: #bfb2bb; }
.app-margin .t2 { background: #978a94; } .app-margin .t3 { background: #74686f; }
.app-margin .t4 { background: #574c53; } .app-margin .t5 { background: #41373e; }
.app-margin .liquidez { background: repeating-linear-gradient(45deg, #4a3d46 0 3px, #2a2128 3px 6px); }

.mg-tabla { display: flex; flex-direction: column; }
.mg-fila, .mg-activo {
  display: grid; grid-template-columns: minmax(0, 1fr) auto 84px;
  align-items: center; gap: 10px;
  width: 100%; text-align: left;
  background: none; border: 0; border-top: 1px solid var(--borde);
  color: inherit; font: inherit; padding: 8px 2px; cursor: pointer;
}
.mg-fila:first-child { border-top: 0; }
.mg-fila:hover, .mg-activo:hover { background: rgb(255 255 255 / .03); }
.mg-fila-liquidez { cursor: default; }
.mg-fila-liquidez:hover { background: none; }
.mg-fila-nom { display: flex; align-items: center; gap: 8px; min-width: 0; }
.mg-fila-txt { display: flex; flex-direction: column; min-width: 0; }
.mg-fila-nom b { font-family: var(--fuente-mono); font-size: 13px; }
.mg-fila-nom small {
  color: var(--texto-tenue); font-size: 11.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mg-marca { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.mg-fila-precio, .mg-fila-valor { font-family: var(--fuente-mono); font-size: 12.5px; text-align: right; }
.mg-fila-valor { font-weight: 600; }
.mg-fila .mg-chip, .mg-activo .mg-chip { justify-self: end; }

.mg-mov {
  display: grid; grid-template-columns: 82px minmax(0, 1fr) auto; gap: 10px;
  padding: 7px 0; border-top: 1px solid var(--borde); font-size: 12.5px;
}
.mg-etq + .mg-mov { border-top: 0; }
.mg-mov-dia { color: var(--texto-tenue); font-family: var(--fuente-mono); font-size: 11px; }
.mg-mov-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mg-mov-imp { font-family: var(--fuente-mono); }

/* --- Mercado --- */
.mg-activo { grid-template-columns: minmax(0, 1fr) 84px 92px 74px; border-radius: 8px; }
.mg-activo .mg-fila-nom { flex-direction: column; align-items: flex-start; gap: 0; overflow: hidden; }
.mg-fila-nom small { max-width: 100%; }
.mg-activo.activo { background: var(--panel-alto-solido); }
.mg-mini .mg-grafica { height: 28px; }
.mg-det-cab { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.mg-det-id { font-family: var(--fuente-mono); font-size: 15px; }
.mg-det-nom { color: var(--texto-tenue); font-size: 13px; }
.mg-det-pie {
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--borde);
  font-size: 12.5px; color: var(--texto-tenue);
}

/* ============================================================
   LA TARJETA DE GLIM — «captura» de Margin con titular
   ------------------------------------------------------------
   Ocupa el mismo marco 4:5 que una foto del feed. Las medidas van
   en `cqw` (ancho del propio marco): el post se ve igual de
   proporcionado en la ventana pequeña y ampliado.
   `--cuenta` es el color de la cuenta que lo publica: solo tiñe la
   etiqueta, para que cada página de noticias tenga su firma.
   ============================================================ */
.mg-tarjeta {
  container-type: inline-size;
  aspect-ratio: 4 / 5;
  display: flex; flex-direction: column;
  box-sizing: border-box;
  padding: 7cqw 7cqw 5cqw;
  background:
    radial-gradient(120% 70% at 100% 0%, rgb(255 255 255 / .05), transparent 60%),
    var(--fondo);
  color: var(--texto);
  font-family: var(--fuente-texto);
  --cuenta: var(--texto-tenue);
  --mg-sube: var(--acento-esmeralda);
  --mg-baja: var(--acento-carmesi-suave);
  --mg-rgb-sube: var(--rgb-esmeralda);
  --mg-rgb-baja: var(--rgb-carmesi);
  user-select: none;
}
.mg-tj-cab { display: flex; justify-content: space-between; align-items: center; }
.mg-tj-fuente { font-family: var(--fuente-ui); font-weight: 700; font-size: 3.6cqw; }
.mg-tj-tag {
  font-family: var(--fuente-mono); font-weight: 600; font-size: 2.6cqw; letter-spacing: .08em;
  color: var(--cuenta); border: 1px solid var(--cuenta); border-radius: 99px;
  padding: .5cqw 2.2cqw;
}
.mg-tj-titular {
  font-family: var(--fuente-titular); font-size: 8.2cqw; line-height: 1.04;
  margin: 5cqw 0 4cqw; text-wrap: balance;
}
.mg-tj-cot { display: flex; justify-content: space-between; align-items: flex-end; gap: 3cqw; }
.mg-tj-activo { display: flex; flex-direction: column; }
.mg-tj-activo b { font-family: var(--fuente-mono); font-size: 5cqw; }
.mg-tj-activo small { color: var(--texto-tenue); font-size: 3.2cqw; }
.mg-tj-precio { display: flex; flex-direction: column; align-items: flex-end; gap: 1.2cqw; }
.mg-tj-precio > span:first-child { font-family: var(--fuente-mono); font-weight: 600; font-size: 6cqw; }
.mg-tarjeta .mg-chip { font-size: 3cqw; padding: .4cqw 1.6cqw; border-radius: 1.4cqw; }
.mg-tj-graf { flex: 1; min-height: 0; margin: 3cqw -2cqw 0; }
.mg-tj-graf .mg-grafica { height: 100%; }
.mg-tarjeta .mg-rangos { margin-top: 2cqw; gap: 1cqw; }
.mg-tarjeta .mg-rango { font-size: 2.8cqw; padding: 1cqw 0; border-radius: 1.4cqw; cursor: default; }
.mg-tj-pie {
  margin-top: 3cqw; text-align: center;
  font-family: var(--fuente-mono); font-size: 2.5cqw; color: var(--texto-tenue); letter-spacing: .06em;
}

/* ============================================================
   RIFT LEGENDS — las partidas de la historia (src/apps/rift.js)
   Misma paleta que Vapor: es el juego que Vapor lanza.
   ============================================================ */
.app-rift {
  display: flex; flex-direction: column;
  width: 100%; height: 100%;
  background: radial-gradient(120% 80% at 50% 0%, #17233a 0%, #0d1420 60%);
  color: #dbe4ee;
  --rf-panel: #141d2b; --rf-borde: #26313f; --rf-azul: #4a9eff;
  --rf-oro: #f0c674; --rf-tenue: #8a97a8; --rf-win: #4ac47a; --rf-loss: #e06666;
}
.rf-cab {
  display: flex; align-items: center; gap: 16px;
  padding: 14px 20px; border-bottom: 1px solid var(--rf-borde);
}
.rf-tit { display: flex; flex-direction: column; min-width: 0; }
.rf-tit b { font-size: 18px; font-weight: 800; letter-spacing: 3px; color: var(--rf-oro); }
.rf-tit small { font-size: 11.5px; color: var(--rf-tenue); }
.rf-marcador { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; }
.rf-marcador small { font-size: 9.5px; letter-spacing: 1.5px; color: var(--rf-tenue); }
.rf-marcador b { font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; }

.rf-zona { flex: 1; min-height: 0; overflow-y: auto; padding: 18px 20px; display: flex; flex-direction: column; gap: 14px; }
.rf-meta { display: flex; justify-content: space-between; font-size: 11px; font-weight: 700; letter-spacing: 1.2px; color: var(--rf-tenue); }
.rf-min { color: var(--rf-azul); font-variant-numeric: tabular-nums; }
.rf-situacion { margin: 0; font-size: 14.5px; line-height: 1.55; color: #e8eef5; }

.rf-opciones { display: flex; flex-direction: column; gap: 8px; }
.rf-op {
  text-align: left; cursor: pointer; font: inherit; font-size: 13.5px;
  padding: 11px 14px; border-radius: 10px;
  color: #dbe4ee; background: var(--rf-panel); border: 1px solid var(--rf-borde);
  transition: border-color .15s, background .15s, opacity .2s;
}
.rf-op:hover:not(:disabled) { border-color: var(--rf-azul); background: #18243a; }
.rf-op:disabled { cursor: default; opacity: .35; }
.rf-op.elegida { opacity: 1; border-color: var(--rf-azul); background: #18243a; }

.rf-jugando { text-align: center; font-size: 13px; color: var(--rf-azul); letter-spacing: 1px; animation: rf-latido 0.9s ease-in-out infinite; }
@keyframes rf-latido { 50% { opacity: .45; } }

.rf-res { border-radius: 10px; padding: 12px 14px; background: var(--rf-panel); border-left: 3px solid; }
.rf-res.win  { border-color: var(--rf-win); }
.rf-res.loss { border-color: var(--rf-loss); }
.rf-res b { font-size: 13px; letter-spacing: 2px; }
.rf-res.win b  { color: var(--rf-win); }
.rf-res.loss b { color: var(--rf-loss); }
.rf-res p { margin: 6px 0 0; font-size: 13.5px; line-height: 1.5; }

.rf-final { text-align: center; font-size: 22px; font-weight: 800; letter-spacing: 3px; padding: 8px 0 2px; }
.rf-final.win  { color: var(--rf-win); }
.rf-final.loss { color: var(--rf-loss); }
.rf-lista { display: flex; flex-direction: column; gap: 6px; }
.rf-fila { display: flex; align-items: center; gap: 10px; font-size: 13px; padding: 8px 12px; border-radius: 8px; background: var(--rf-panel); }
.rf-fila-res { font-weight: 800; width: 16px; text-align: center; }
.rf-fila.win  .rf-fila-res { color: var(--rf-win); }
.rf-fila.loss .rf-fila-res { color: var(--rf-loss); }

/* Centrado: a la derecha lo tapan los avisos de la esquina */
.rf-pie { margin-top: auto; display: flex; justify-content: center; gap: 10px; padding-top: 4px; }
.rf-saltar {
  cursor: pointer; font: inherit; font-size: 12px; padding: 7px 12px; border-radius: 8px;
  color: var(--rf-tenue); background: transparent; border: 1px solid var(--rf-borde);
}
.rf-saltar:hover { color: #dbe4ee; border-color: #3a4656; }
.rf-sig {
  cursor: pointer; font: inherit; font-size: 13.5px; font-weight: 700; padding: 10px 18px; border: none; border-radius: 10px;
  color: #fff; background: linear-gradient(135deg, #3a8bff, #2358c9);
}
.rf-sig:hover { filter: brightness(1.08); }

/* =========================================================
   GALERÍA CON CANDADO (solo edición gratuita)
   ========================================================= */
.app-galeria-mecenas {
  flex-direction: column;
  align-items: center;
  width: 100%;
  overflow-y: auto;
  padding: 26px 28px 22px;
  text-align: center;
}
.gm-candado {
  font-size: 34px;
  color: #3DE0D5;
  filter: drop-shadow(0 0 12px rgb(61 224 213 / .45));
}
.gm-tit {
  margin-top: 12px;
  font-family: var(--fuente-ui); font-size: 18px; font-weight: 700;
}
.gm-sello {
  margin-top: 8px;
  padding: 3px 10px;
  border: 1px solid rgb(245 196 107 / .5);
  border-radius: var(--radio-capsula, 999px);
  color: #f5c46b;
  font-family: var(--fuente-mono); font-size: 10.5px;
  letter-spacing: 1.5px; text-transform: uppercase;
}
.gm-lista {
  margin: 20px 0 0; padding: 0;
  list-style: none;
  display: flex; flex-direction: column; gap: 10px;
  text-align: left;
  font-size: 13px; line-height: 1.5; color: var(--texto-tenue, #aab);
}
.gm-lista li { padding-left: 16px; position: relative; }
.gm-lista li::before {
  content: ''; position: absolute; left: 0; top: .6em;
  width: 6px; height: 6px; border-radius: 50%;
  background: #3DE0D5;
}
.gm-pie {
  margin-top: auto; padding-top: 18px;
  font-size: 12px; color: var(--texto-tenue, #aab);
}
